CapeSoft.Com
Clarion Accessories
Multi-Proj
Documentation
Multi-Proj Tutorial
CapeSoft Logo

CapeSoft Multi-Proj Tutorial
Documentation

Download Latest Version FAQ History
Installed Version Latest Version

Tutorial: Writing Multi-DLL Applications in Clarion using CapeSoft's Multi-Proj

There comes a point when writing applications when you start to think about splitting them up into multiple DLL's. In this tutorial I'll describe the issues involved. I'll also show you how Multi-Proj simplifies this task, and where it can be used to make your life easier.

Basic Introduction

First some basics. You may already know this stuff (in which case you can jump to the next section) - but feel free to review it here.

Firstly, what is a DLL? A DLL is a Dynamic Link Library. In essence this means it is a Function Library which is stored in a separate file on your disk (cunningly with a DLL extension). The alternative to this is a Static Link Library. This is a Function Library which is Linked into your EXE when your program is compiled.

Figure 1

The advantages of DLL's are numerous, but the most useful advantages are:

a) The DLL can be replaced (i.e. fixed) without replacing the whole program.
b) Multiple programs can use the same DLL, thereby saving disk space.

In Clarion terms, an APP file can be compiled into either an EXE, a DLL or a LIB file. You may have been used to a single, ever growing, APP file - which compiles into an EXE. For Clarion developers the advantage of splitting your APP into multiple DLLs include faster compiles, faster loading (of the APP file into Clarion) and a faster edit-compile-test cycle. A disadvantage of splitting your product into multiple APP files is that the administration effort for the product as a whole goes up. While Clarion supports Multi-DLL products, it certainly doesn't make it easy. This is why we wrote Multi-Proj, it creates the needed link between the APP files, which eases your admin burden.

When Clarion compiles your APP file as a DLL, a number of files actually get created. We'll explore what the files are, and what they do here.

DLLThis is the function library itself. It contains all your actual code. This is the only file that needs to be distributed with your final product.
LIBEven though the APP is a DLL, and not a Static LIB file, it does in fact still create a LIB file as well as the DLL. (This LIB file is sometimes called a STUB). The LIB file in fact contains the link between the EXE and the DLL. The small LIB file will eventually be linked into your EXE, and it will allow the EXE to use the DLL.
EXPThe EXP file is essentially a small text file which tells the compiler what to put into the LIB file. EXP stands for Export and it's essentially a list of things that must be Exported from the DLL to the EXE.
Figure 2

This brings us to an interesting point. A DLL does not necessarily have to Export everything that it contains. A DLL can contain any combination of Data, Procedures and/or Classes. But the DLL doesn't need to expose all of its components to the EXE - and advantages of that will be discussed in more detail later.

To use a DLL you have created in another APP file (that APP file can itself be either another DLL or an EXE) you need to do up to 4 things:
  1. The LIB part of the DLL needs to be added to the APP's Project Files.
  2. The Functions exported from the DLL need to be Prototyped in the Global Map.
  3. The Global Data fields exported from the DLL need to be added to the Global Data section.
  4. If the DLL is an ABC DLL then it needs to be initialized.

In addition, if you are to obtain full benefit from the DLL then it's really useful to document it properly. This allows other developers in your team, or outside your team, to make use of the functions you've created. Also if the template is properly documented then you're more likely to use it yourself in future applications.

This can make using the DLL quite tedious as there is substantial overhead on the developer side to keep everything in sync. As we'll see later Multi-Proj offers not only great features for managing the creation of the DLL - it also offers great features for using the DLL.

Once you have all your apps, happily creating multiple DLL's, and EXE's, then the next thing to look for is some sort of Batch Compiler. This is a special tool which allows you to compile multiple apps with a single click. This makes the process a lot more automatic than opening each APP - compiling - closing - opening the next and so on...

Another thing to consider is that the version you ship is not necessarily the version you'll be compiling along the way. The reason for this is that while you're developing it's useful to be compiling with all the Debugging options turned on - but when you come to release you'll want to switch these options off. This reduces your file size by a huge amount.

Aside: Did you know? If you Install the Clarion Debugger as your System Debugger then whenever your program GPF's there will be a DEBUG button on the GPF window? If you click on the DEBUG button - and your APP is compiled with debugging turned on - then the Clarion debugger will spring to life and take you to exactly the line of code that caused the GPF. To install the debugger as your System Debugger Run the \Clarion\Bin\C5DBx.exe - Go to the Setup menu and Choose "Install as System Debugger".

Once everything is compiled there is the issue of distribution. Very often the new DLL's will need to be copied somewhere on your drive - to the Clarion BIN directory, or to a directory where it can be added to a distribution set.

Planning to Split up your App

There are no rules on how to split up your application. Everybody does it slightly differently, but the aim is to split up the application into "bite" size chunks, that are still usable and efficient. I'll show you a basic approach in this section and also an example of how not to do it.

The first place to begin is by designing how you're going to split up your APP. The first break-up looks like this:
(A)EXE
Application
This contains the Frame plus any high level miscellaneous windows like the About screen, and Splash screen. This APP uses no file structures (although it usually points to the dictionary).
(B)Data DLL ApplicationThis APP contains just the Data declarations - and no procedures (except maybe procedures that are supposed to be here - like the File Manager 3 "RuntimeFileManager" procedure).
(C)Other DLL ApplicationAll the other procedures - including Browses, Forms and Reports.

Of course this is just the beginning. So far you haven't done very much at all. You still have one large APP marked (C) in the above table and two small apps (A) and (B). However it's a good idea to get to this point first. It will allow you to make sure everything is working - and set up correctly before moving on.

When this is successfully compiling (we're going to look at the mechanics of it all in the next section) then you split up (B) further. How you do it is mostly up to you, but there are a couple of possible strategies. There is only one rule you have to observe though, and that is easiest described like this;

The DLLs have to be put together in Levels. Each DLL can only use other DLLs which are in a Lower level. For example in the simple split above we have 3 levels. The lowest level (level 1) is the Data DLL and this is used by both of the "Other" DLL and the EXE APP. The "Other" DLL is level 2 - that is, it can use the Data DLL - but it can not call any of the procedures in the EXE (which is in level 3).
3 level application

Lets give an example of how not to break up an application. Lets say we split the APP up some more so that we had:
(A)EXE
Application
This contains the Frame plus any high level miscellaneous windows like the About screen, and Splash screen. This APP uses no file structures (although it usually points to the dictionary).
(B)Data DLL ApplicationThis APP contains just the Data declarations - and no procedures (except maybe procedures that are supposed to be here - like the File Manager 2 "RuntimeFileManager" procedure).
(C)Browse DLL ApplicationThis contains all the Browses.
(D)Forms DLL ApplicationThis contains all the Forms.
(E)Reports DLL ApplicationThis contains all the Reports.

In this case the Data APP would be level 1. The Reports APP would be level 2. The Forms APP would be level 3. The Browse APP would be 4 and the EXE APP would be level 5. How did I decide this? Well I did it in order of dependencies. The Data APP is dependant on nothing. The Reports need the Data. The Browse needs the Forms (i.e. the Browse procedures call the Forms procedures) and so on.

5 level application

How not to break up an application

The Levels rule can be quite restrictive. For example the above breakdown is almost certainly not going to work. What happens if I have a Form, which calls a Lookup? the Lookup is a Browse - but the Form DLL is a lower level than the Browse so it can't work. This is the reason that simply splitting your APP based on template type almost certainly won't work. It is however a good place to start. The concept of splitting the reports out, and indeed the processes (you can keep the Reports and Processes together - or separate them - it depends on how many you have).

You can of course simply put all your browses and forms together (if you have lots of reports this might be ideal anyway) but if your apps are like mine then this DLL would dwarf all the others. In this case it's a good idea to split them up based on what procedures go together. For example the Customer browse and Form, plus all the Customer Related browses and forms can go in one DLL, while the Product browse and form etc can go in another.

The last issue when it comes to splitting them up is How big should each APP be? Well there's no right answer but a rule of thumb which I use is that a compiled DLL or EXE (without debugging code) should be smaller than a Meg in size. This is useful if for no other reason than that it fits nicely on a floppy disk. Of course sometimes I go over a meg - and sometimes the DLL's are much smaller than a meg - this is just a guideline. Another thing to consider is the size of the APP file. The larger the APP file the longer it takes to load and unload. I prefer to keep them around a meg in size. If your APP seems to take a really long time to load, or unload, then this is a good sign to either break up the APP a bit, or invest in more RAM.

So in this example we will spit our application into the 3 parts described in the top of this chapter.

The Basic Tutorial

We are going to take an existing complete single EXE application (provided in the examples directory as whole.app) and split it up into a Multi-DLL application. We will use the Multi-Proj template as we go. At the end of the tutorial we will end up with the following scene:

Aim of the Tutorial

This is a trivial example application, which you could use to model breaking up your own application. In your case you may want to break up the equivalent of your procs.app into further smaller DLLs.

Tutorial Requirements: Single EXE Application (Whole.app)

Before we split up the Single EXE application you may want to load it to see what it does. This application is called Whole.app and is found in the \Clarion\3rdParty\Examples\MultiPrj\Tutorial folder.

This application has a number of procedures which include a main frame, several browses, forms and reports and a splash screen.

Whole.app Application Tree

You will need to compile this application before you can run it.

Of course this is a small app - you wouldn't normally break up such a small app - but it serves as a manageable example. One thing to note is that although this application is an ABC application, the process is exactly the same for a Legacy application.

Overview

What we are about to do

In order to split this Single EXE application into a multi-DLL application we will need to do the following things that are explained in greater detail in the following sections:
  1. Create the DATA DLL from scratch (which we will call AllFiles.app). This will create a template for us to use in the other apps.
  2. Register this new template.
  3. Create the "other" DLL (which we will call Procs.app).
  4. Import functions from the existing Single EXE application into the Procs Application (part of our new Multi-DLL application).
  5. Create the EXE (which we will call Main.app)
  6. Import Functions into the Main Application

1. Creating the Data DLL

The first step we need to do is to create a new application from scratch that will be our DATA DLL. New Application (allfiles.app)

When the Application Properties screen appears: AllFiles.app Application Properties

Okay - so this creates a small APP which looks like this:

AllFiles.app Application Tree

Using the Multi-Proj Global Extension Template AllFiles Global Properties General Tab
AllFiles Global Properties File Control Tab
NETTALK TIP : If you have installed NetTalk on your system, then go ahead and add either the Suppress NetTalk or Activate NetTalk global extensions here. Because this is a Data DLL you need to add one of these 2 extensions.

TIP : If you open the AllFiles.app, from the CompletedTutorial folder, and you do not have NetTalk installed (shame on you) then you will get a Generator warning : "Unknown Template Type Activate NetTalk". You can ignore this error by clicking on OK.

Now we get to the really nice bit - this is where you add Multi-Proj to this DLL.

To add the template:
AllFiles Multi-Proj General Tab

To determine the Highest BC number, click on the Project button, and inspect the window that opens.



General Tab Options Explained

The General tab contains a number of options - most of which are used in special circumstances. The first few however are used a lot in Data DLLs. This is what all the options mean:

Export File Structures : All the files structures used in this DLL are going to be exported (i.e. made available) to other DLLs and EXEs. As this is a Data DLL this is exactly what we want. In all the other DLLs and the EXE this will be off. Also if you were making some sort of utility DLL though you might chose not to export the structures, in which case you'd leave this off. An example of this is our Secwin utility. It makes use of a Security file in the DLL, but the Security file structure is not exported to apps that use Secwin. The apps use the Procedures in Secwin, which in turn use the files.

Export Your Global Data : The same as for files. Again because this is a data DLL, we do want to export any global data we define here. Otherwise this would typically be Off.

Export Template Global Data : This should be ticked on only in the data DLL. Everywhere else it must be ticked off.

Export ABC Library : This applies to ABC apps only. Basically in ABC apps this is ticked on for Data DLLs - and Off in all the other DLLs. Remember I said the ABC library was Internal to this APP? Well this is where we make it available to other DLLs (to them it is External).

Export Procedures in Module Order : This is here for backward compatibility reasons. Basically it lets you govern the order in which the Procedures are exported from this app. It is very unlikely that you will use this switch. See the section on Backward Computability for more information on this.

This app has no _rd or _ru modules : This is for Legacy apps only. Tick this on if this DLL doesn't use any files.

This app has no _SF module : This is for Legacy apps only. Tick this on if there is no _sf source module generated with this application. This is quite rare, but can occur.

This APP has no BC modules : This one is for ABC applications and again is quite rare. However if your APP doesn't generate any BC modules then tick this on. BC modules are typically created if the APP uses one or more file structures.

Highest BC number : If this is an ABC, Data DLL, then you need to find out the highest BC number and enter it here. To do this click on the Project button, when viewing teh application, and inspect the Generated Source Files section. In this example this number should be 0.

Big Picture App Number : In order to do rebasing Multiproj needs each DLL app to have a unique number, starting with 1 and counting upwards, for each app in the suite. For more information on this option see the Multi-Proj documentation.

Template Tab

At this point I'm going to skip right over to the Template Tab. We'll come back to the other tabs in a moment. I mentioned earlier that Multi-Proj makes using a DLL much easier. Well it does this by writing a template for you. The template will contain everything we need to make using the DLL, and it's data, trivial. By default the template will contain a Global Extension to Activate the DLL (Add the Library to the Project, Prototype the Functions etc) and also a Code template for each procedure to make calling the procedures in this DLL trivial. AllFiles Multi-Proj Template Tab

Template Tab Options Explained

Template Set Name : This is the name of the template set to which this DLL belongs. One of the features in Multi-Proj is that it lets you build up a template set made up of all the templates for all the DLLs in a product. This makes things easier to manage, and also cuts down on the number of template sets in your registry. Multi-Proj version 1.3 users will see the difference here - in the past Multi-Proj made a separate set for each DLL - This could result in a lot of sets for products with lots of DLLs. I've used the name of the eventual product here as the Set name, but you can use any name you like. All the DLLs in the product can have the same Template Set name. Incidentally you can add your own templates to this set as well - See the Section entitled Expanding the Generated Template.

Template Filename : This is the name of the file which contains the template for this DLL. Each DLL must have a unique name. The most obvious name to use is the name of the APP.

Don't Generate Code Templates : As I mentioned, by default Multi-Proj will generate a code template for each procedure which is exported from the APP. Occasionally you might want to code these templates yourself, by hand. In this case tick this option on to prevent Multi-Proj from doing it for you.

Includes : This is an advanced option. It allows you to manually add hand-coded TPW files to this template set.

Don't Generate Dependency Defines : This is also an advanced option. If this is on then Multi-Proj does not generate dependency information into the template files.

TIP : If you are creating an EXE then there is no benefit in creating a template. So if APP was an EXE then we would leave this tab blank.

Resources Tab

On to the Resources Tab. This is where you get to add stuff to the APP which it must compile into the finished DLL. This is the same sort of stuff which in the past (and you still) have to add to the PROJECT button for your APP. These are things like Extra BMP files, or ICO files, Extra File Drivers and so on. If you have External Source modules being used by your APP then you can add that here as well. There are a couple of advanced options on this tab as well - they'll be discussed in more detail later. AllFiles Multi-Proj Resources Tab

Resources Tab Options Explained

File Drivers : This button allows you to add File Drivers to the APP which the APP doesn't know about. For example if you are using our EzHelp product then you might need to manually add the TOPSPEED driver ( which EzHelp uses ) to this button. This would only happen if your APP doesn't normally make use of this driver, and if the 3rdparty product in question doesn't support Multi-Proj directly. (All CapeSoft products naturally support Multi-Proj directly, as do a number of other 3rd party products. Information on how to support Multi-Proj can be found in the Multi-Proj documentation.)

Common Resources : This section is for resources such as Bitmaps, Icons and so on. We're going to talk about Versions in a minute, and each version can have it's own resources, but the resources on this tab would be Common to all the versions.

External Source : This button allows you to add external source files to your APP. Actually it also lets you add support for a Range of files (i.e. for example DET001.Clw to DET023.Clw) without having to add each on individually. For the most part however you just enter the name of the file you wish to include.

Enable Driver Substitution : If this is ticked on then you'll be able to substitute one file driver for another when the application is generated. As this is the basic tutorial, we'll leave this option off for now. The Driver Substitution Tutorial shows these substitution features in action.

Versions Tab

Finally we get to the Versions tab. However before we look at the options here a short aside is in order.

It's not commonly known, but inside each APP file is a PROJECT. In fact it is the Project that you see when you click on the Project button - and it is the Project which the Compiler and Linker use to create the end product DLL or EXE. Now you may have noticed that Clarion also supports separate Project (PRJ) files. This is primarily there for those folks who don't use the generator, but who rather hand-code their products. It is however this feature which Multi-Proj uses (and where the name originally came from). Multi-Proj allows you to generate PRJ files from your APP. This means that instead of compiling your APP you can compile a PRJ.

Why is this useful? Well Multi-Proj lets you set different settings in your PRJ than are in the APP itself. So the PRJ might (for example) have the Debugging turned off, while the normal APP has it turned on.

But wait - there's more. Multi-Proj lets you create Multiple Projects from the same Application. This means (for example) that you can create a Registered version of your DLL, and an Unregistered version, from the same source code - but 2 different projects.

However even if you don't use the Multi part of Multi-Proj it's still useful to have a project which is different to the APP. Each time you add Multi-Proj to an application you need to add at least 1 version.
AllFiles Multi-Proj Versions Tab

Versions Tab Options Explained
Most of this is very familiar.

Title : This is a name you give to this version. It is just used here for display purposes, so use anything you like.

Set : This is only used if you are making different versions, of the same DLL, with different Target Names. This is covered more fully in the Driver Substitution Tutorial. For this example leave this field blank.

Target Type : Is this a DLL, LIB, or EXE. In this example we're making a DLL.

Target OS : 16-bit or 32-bit (16 bit is included for backwards compatibility, but is no longer actively supported)

Runtime Library : Stand Alone, Local or External. Stand Alone is used when you're making a DLL to be used in other Stand Alone Apps - Local is used to make a LIB which can be used in other Local Apps.

Debugging : On or Off

Target Name : This is the name of the DLL you are going to create. NOTE This is NOT the same name as the APP file!! Each version must have a unique target name. (In this case I'm going to call this AllFil32)

Project Name : If you make 2 versions, with the same Target name (for example a debugging and non-debugging version of the same DLL) then enter a separate project name here. Project names need to be unique across all versions. If the Project name field is blank then the Target name is used for the Project.

Resources : This tab lets you add resources which are specific to this version. This would typically be any external LIB or OBJ files. Note that this tab is only for resources which are version specific. Resources which apply to all versions can be added to the "Global" Resources tab.

File Drivers : This tab lets you add any File Drivers which might be specific to this version. Usually the File Drivers needed by the version will automatically be included, but this tab gives you the opportunity to override the drivers that are linked in.

Defines : In a project it is possible to define what are essentially equates, which can be used in your program. For example if a particular version is a demo version, then you might create a define called Demo. To set the equate here you use a slightly different syntax to the normal way of programming. Instead of saying Demo=1 you rather say Demo=>1
Hey I didn't invent this - this is just how it's done .... In your code you can use this to include or exclude code. For example to add some code if this is a demo version...

COMPILE ('***',Demo=1)
  Message('This is a Demo version. Please Pay!')
***


Distribution : After compiling a particular project it is often useful to copy the resultant files to another directory. For example DLL files are often sent to the Clarion\Bin directory, Lib files to Clarion\Lib - EXEs and DLLs to a distribution directory, and so on. On this tab you can enter as many of these distributions as you like.

TIP : This is also a great place to copy other files which belong to the project, but which may have changed. For example Help files, or sample data files etc.

Target name of the Application

Okay, now we've seen the Multi-Proj extension, we're almost ready to continue splitting the original app. Before we go any further though there's one last thing to do, and that is to set the name of the Target in the Application itself.

By default Clarion creates a DLL with the same name as the App file. So in this case it would create AllFiles.DLL. But in the version above we asked it to create AllFil32.Dll. Remember I started this tutorial by saying that there is already a project in the APP file - Multi-Proj is simply adding More projects. What we're going to do now is adjust the APP's project to fit in with our new naming scheme.
AllFiles Application Tree

This takes you to the Project Editor. Remember we're editing the Project inside the APP file now.
AllFiles Global Options
AllFiles Global Options

In this editor you use the Properties button to set the APP to be similar to one of your versions. I say similar because you probably won't make it exactly the same. One obvious change is to turn the Debugging options in the APP On, but leave them off in the Multi-Proj project (We're going to continue using the APP as normal during the development process - we're just going to use the new Multi-Proj PRJ file for the final release). AllFiles Project Editor

We set the Target File of the Application to match that of the the Multi-Proj one. This allows us to create and use the same name for the DLL when we develop and when we ship (release) our product. (In the case above the Application's DLL (allfil32.dll) is set to 32-bit with debugging on, while the Multi-Proj one (also allfil32.dll) is 32-bit with no debugging. The later is the one you will use when you release your product.

Creating the Template

As we explained earlier Multi-Proj creates a template for you. This is automatically created when you generate and compile your project.
This will build your new template as well as your new Data DLL (allfil32.dll)

NETTALK TIP : If you get about 95 errors, starting with one similar to;

Link Error: Unresolved External NetDUNRename

then you probably have NetTalk installed on your system. Because NetTalk is an ABC compliant object, that uses a compiled DLL, AND this is a Data DLL, you must add either the Activate NetTalk Global Extension, or the Suppress NetTalk Global Extension to the application. See the list of errors in the Multi-Proj Complete Documentation for more information.

Should you have any other compile errors, look here at the list of errors in the Multi-Proj Complete Documentation.

2. Registering the New Template

You now get to register the new template.

To do this:
You won't have to re-register the template again - and any other DLL's we add to this template set will automatically be registered for you. We'll see that when we create the next DLL.

3. Creating the Intermediate "Other" DLL (Procs.App)

Each Multi-DLL product consists of at least 2 parts - the Data DLL (which we've just made) and the EXE (which we'll make later). In-between these 2 pieces you can create any number of Intermediate DLLs. In this example I'm only going to make 1 - but you might make more. Each one is created along the same lines so this example should be all you need to get going.

As before create a new APP (I'm going to call it Procs). New Application (procs.app)

When the Application Properties screen appears: Procs.app Application Properties

Okay - so this creates another small APP which looks like this:

Procs.app Application Tree

As before the APP tree will appear, and the first thing to do is :
This is where we come across the first difference between the Data DLL and a Procedures DLL. Procs Global Properties
Procs Global Properties

Now we add the Multi-Proj template again.
Procs Multi-Proj General Tab

Procs Multi-Proj Template Tab

You do not need to do anything in the Resources Tab Procs Multi-Proj Versions Tab

Adding the AllFiles Template

Once the Multi-Proj extension is added, we need to add the AllFiles Template that we created when we compiled the Data DLL (AllFiles.app). Because this APP is going to make use of the Data DLL (AllFil32.DLL) you need to add its Activate AllFiles Functions Extension.
Procs - Adding AllFiles Template

Application Project Properties


As before we need to change the application's project target name.
Procs Application Tree

This takes you to the Project Editor. Remember we're editing the Project inside the APP file now.
Procs Global Options
Procs Global Options
Procs Project Editor

Okay - that's the setup out of the way - as you can see it becomes a lot easier, and quicker, as you get used to it. Now lets import some of the functions from the Whole.App into this DLL.

4. Importing Functions into the Procs Application

What we want to do now is to import the functions in the existing Single EXE (Whole.App) into our Multi-DLL application.
Procs - Select application to import from

In this case we're going to import all the functions, excepting the Main and Splash functions.

Clarion 2 Users: You will not have a Splash function in this tutorial.
Procs - Select items to import

This will result in the APP tree looking like this:

Procs Application Tree

One important point to note here is that currently NONE of these procedures will be exported to other applications. So at this point you have to decide which functions should be Exported (and hence available to other APPs). The simple answer is "All of them" - and there's not much wrong with that.

To set a procedure as exported
Procs - Procedure InvoiceReport Properties
Should you have any compile errors, look here at the list of errors in the Multi-Proj Complete Documentation

5. Creating the Main EXE Application

The last step is to create the EXE Application which will use the DLLs. This is a pretty straight forward process. As before we create an app - I'm going to call this one Main.

As before create a new APP (I'm going to call it Main). New Application (Main.app)

When the Application Properties screen appears: Main - Application Properties

Okay - so this creates another small APP which looks like this:

Main - Application Tree

As before the APP tree will appear, and the first thing to do is :
Main Global Options
global properties file control tab screenshot

Now we add the Multi-Proj template again.
Main - Multi-Proj General Tab
Main - Multi-Proj Template Tab

You do not need to set this up for an EXE, as other parts of your project can not talk to an EXE. This is what DLLs are for, and so we can leave this blank.

You do not need to do anything in the Resources Tab Main - Multi-Proj Versions Tab

Adding the AllFiles Template

Once the Multi-Proj extension is added, we need to add the AllFiles Template that we created when we compiled the Data DLL (AllFiles.app). Because this APP is going to make use of the Data DLL (AllFil32.DLL) you need to add its Activate AllFiles Functions Extension.
Main - Adding AllFiles Template

Adding the Procs Template

Once the Multi-Proj extension is added, we need to add the AllFiles Template that we created when we compiled the Data DLL (AllFiles.app). Because this APP is going to make use of the Data DLL (AllFil32.DLL) you need to add its Activate AllFiles Functions Extension.
Main - Adding Procs Template

Application Project Properties

As before go we need to set the Application Project Properties.
Main Global Options
Main Global Options
Main - Project Editor

6. Importing Functions into the Main EXE Application

What we want to do now is to import the remaining functions (Main and Splash) from the existing Single EXE (Whole.App) into our Main application.
Main - Select application to import

In this case we're going to import the Main and Splash functions.
Main - select items to import
Main - Procedure Name Clash

This will result in the APP tree looking like this:

Main - Application Tree

The last thing to do is handle all of these ToDo's. Actually this part might also crop up when you split up the Procs DLL (if you do that). The method of getting rid of these ToDo's is slightly different to the normal Clarion method. To set these procedures as external, repeat the following process for each ToDo procedure:
select module type
module main009.Ico properties
Main - Select Procedure Type
procedure view customers properties
This is done so that you don't have to go to the extra step of adding each external Library manually to the Application Tree. This is normally a requirement - especially for ABC applications - but effectively prevents you from creating multiple versions. Multi-Proj saves you time, and adds functionality, if you use this External Procedure.

You should now end up with an application tree that looks like this:

Main - Application Tree

Okay, that's the EXE taken care of.

What have we done so far?

We have split the whole.app application into 3 separate applications. Two of these are DLLs and the other one is the main.exe

tutorial_aim.gif (9012 bytes)

We have compiled the two DLLs (allfil32.dll and procs32.dll) and main32.exe in the Clarion IDE. This results in us having a debug version of the DLLs and the main32.exe so that we can debug our project. The next section will show you how to use the Multi-Proj Manager to produce non-debug versions of these DLLs and main32.exe so that you can ship your product to your clients.

Batch Compiling via Multi-Proj Manager (Tutorial part 2)

The next step in the process happens, not inside the CW IDE, but outside of it. Well almost. The idea is that now your product is made up of a number of DLLs and an EXE, you want to be able to generate, and compile them all as a single event. This is made possible using the Multi-Proj Manager.

Please note that you do not have to have done the first part of the tutorial to this second part of the tutorial. If you did not do the first part then please look out for the I did not do the first part of the Tutorialsigns.

To run the Multi-Proj Manager (MPM)
Clarion Accessories Menu

This will load MPM. The MPM main screen looks something like this:

Multi-Proj Manager

In this case we want to add a new Batch.
I did not do the first part of the Tutorial Adding main32.prj

This Main32.prj was the project that the Multi-Proj template created for us. Because Multi-Proj understands project dependencies, selecting just this one file will load all the applications and projects that are needed to create this version of your product.

Remember in the Tutorial we told Multi-Proj that we wanted a non-debug version of this product. So when we make this project we will end up with a non-debug version of the project which you could ship to your clients. Multi-Proj is excellent at providing you with different versions. You can choose to have debug, non-debug 16-bit or 32-bit versions. You can program and edit using debug versions, but using the Multi-Proj Manager you can press one button and suddenly you have a non-debug version ready for shipping to clients.

Multi-Proj Manager gives you 4 different types of generates and compiles.

Generate: A Generate will generate the clarion source code files. i.e. It will create the .clw files. It will not build an EXE or DLL. Only applications can be generated (projects are ignored).

Make: A Make will generate applications and compile applications and projects to form EXEs or DLLs.

Smart Make: A Smart Make will generate applications and compile projects. This is very useful when you are building multi-DLL projects using the Multi-Proj template. You applications are generated, and then your project files which have your compile settings for shipping your project are used to build the final EXEs and DLLs.

Compile: A Compile will compile projects. (Applications are ignored). This means that the the .clw files are compiled and linked to form an EXE or DLL.

I did not do the first part of the Tutorial
If you did not do the full tutorial then you need to do the following to register a new Template that Multi-Proj will create on your machine.
Because we are using Multi-Proj, we want to use the Smart Make, which will generate our applications (but not compile them) and compile our Multi-Proj projects. This will create our non-debug version of our program. Multi-Proj Manager After Smart Make

The full documentation for the Multi-Proj Manager can be found in the Complete Multi-Proj Manager Documentation.

The Driver Substitution Tutorial

The Data DLL
The Procs DLL
This Tutorial starts where the Basic Tutorial finishes.

The goal of this tutorial is to create 2 sets of the program, where each set uses a different File Driver.

A completed set of files for this tutorial can be found in the \Clarion\3rdparty\Examples\Multiprj\DriverTutorial filder.

During this tutorial we will take the original application (already split using the Basic tutorial) and set it so that it generates both a TOPSPEED version, and a MSSQL version.

The Data DLL - Multi-Proj Extension

Open the Data DLL (Allfiles.App) in the Clarion IDE.
Go to the Global Extensions
Highlight the Multi-Proj extension, and go to the Resources tab.

Tick on the option Enable Driver Substitution. Then click on the Override Driver Possibilities button. Click on Insert to add an override possibility.

Tip : In this example I'm only going to create 1 override, changing Topspeed files to MsSQL files. However you can add as many different overrides as you like here. I recommend doing one at a time though until you get the hang of it.
override driver possibilities screenshot

Ok, That's the resources tab taken care of, now move to the Versions tab.

First make 2 changes to the version that is already there.
versions details screenshot
versions defines screenshot

Ok now we're ready to add the second version. In many ways this is similar to the first;
versions details screenshot

On the File Drivers Tab Add the MSSQL driver, plus any other driver that this version will need. Almost always the DOS driver is necessary.
versions file drivers screenshot

On the Defines tab notice that this version has the MSSQLDRIVER define turned on and the TOPSPEEDDRIVER turned off.
versions defines screenshot

The Data DLL - Global Data

If you don't already have one, create a global data variable called glo:owner. this should be a String 255. Remember we used this on the Resources tab when we created the MsSQL option.

The Data DLL - The Connect Procedure

When you are going to use a SQL backend, instead of a Topspeed backend, then you'll need to add a Connect procedure to your application. I like to put this in the Data DLL, because it s fundamentally related to the data.

The exact way you do your connect procedure will depend on your particular circumstances. If you have File Manager 3 (for example) then it already has features to help you make this procedure.

The goal of the Connect procedure is simply to set the glo:owner variable appropriately, and then to open a file. This procedure can be very simple, or more complicated depending on your personal style. In the completed tutorial you'll find a Connect procedure that I use.

Notice particularly the way you can use conditional compile statements to make the behaviour different in each version. For example in the Topspeed version the connect procedure actually does nothing, it simply returns to the caller.

The Connect procedure needs to be called, and a good place to call it from is the Global Setup Program Embed (in the Data DLL).

Tip : What a lot of people don't know is that in a multi-dll situation the code in the Data DLL is actually run, before the start-up code in the exe. Since you need to connect to the database before pretty much anything else happens, a good place to call the Connect procedure is in the Data DLL.

The Data DLL - Project Settings

As you know by now Multi-Proj generates a number of PRJ (Project) files - one for each version you are making. But in the APP itself is also a built-in Project. Since it's important that the App continues to compile, it's a good idea to set the DEFINES in this project as well.

With the App open
click on the Project button
click on Properties
and go to the Defines tab.
there, set the 2 defines.
We could choose either of the versions, but in this case I'm going to set the APP to compile the Topspeed version.

global option defines tab screenshot

Now go ahead and compile the Data DLL, to make sure it still compiles ok.

The Procs DLL - Activate Allfiles Extension

The last thing we set in the Data DLL was the settings for which version the Data APP will actually make when it is compiled. Similarly we need to set the Procs DLL. The first place to do this is on the Activate AllFiles global Extension. Select from the list of SETS, and set this APP to use the TPS set.

extension and control templates screenshot

The Procs DLL - Project Settings

In the same way as we did for the Data DLL, The Procs DLL needs to have the internal project settings set.

Procs DLL - Project Settings screenshot

The Procs DLL - Multi-Proj Extension

The necessary additions and changes here are exactly the same as for the Data DLL. In summary;

The Main EXE

The settings for the Exe, follow the same as for the Procs DLL.

In summary;