Version

www.capesoft.com
Updated 21 June 2005
     


Additional Documentation Guide
   
     



Contents
  Introduction  
How to get Technical Support
How Does It Work?
Multi-Proj Global Extension Options
  General Tab
  Versions Tab
  Resources Tab
  Template Tab
Bulk Generating and Compiling
Using a Multi-Proj DLL in Another Application
External Functions in the Application Tree
Tips [recommended reading]
List Of Errors [recommended reading]
Driver Substitution
3rd Party Support for Multi-Proj
DLL Backward Compatibility
Conditional Compiles
DLL Naming Strategies
Copyright & License
Version History
     

Introduction

Automatic Project Management for Clarion

Multi-Proj is a comprehensive tool for the rapid creation, maintenance, and use of DLLs in Clarion for Windows.

If you have any of the following situations then you are a candidate for Multi-Proj

When your program grows large, there comes a point when you start to consider breaking it up into many app files, that create DLL's.  This process can lead to quite a bit more overhead, functions have to be prototyped, procedures need to be exported, and so on.  Multi-Proj has been designed to automate as much of this Multi-App-Management as possible. It also allows you finer control over how each application interacts with the others.

Another popular use for Multi-Proj, even if you only have one app file, is the ability to create versions that substitute a different driver than the one specified in the dictionary.  This means, for example, that migrating from one driver to another is much easier with Multi-Proj especially if you need to maintain support for both drivers.

It should be noted that this is a developer-level tool.  In other words it gives you, the developer, more power, and more flexibility than before.  The cost of this power is knowledge. When you know what you're doing, Multi-Proj is on you side. When you don't know what you're doing then it can cause you grief. Please take the time to work through the tutorial.

Multi-Proj continually maintains all the related files, including the EXP files, PRJ files, distribution commands, and maintenance of the template file - automatically. Now changing a DLL becomes as simple as compiling a single batch. All of the rest of the work is taken care of.

Another thing we regularly do now, is compile all our APPs during the development cycle with Full Debugging turned on. However Multi-Proj generates Debug Free PRJ files for us, which we compile just before distribution (with the Multi-Proj Manager - a Batch Compiler). Thus our clients get the leanest code possible - while we can make full use of Clarion's native debug facilities.

How to get Technical Support

CapeSoft Support
  Email support@capesoft.com  
Telephone +27 21 715 4000
Fax +27 21 715 2535
Post PO Box 511, Plumstead, 7801, Cape Town, South Africa
     
Multi-Proj is available for purchase at $149 from:

CapeSoft Sales
  Web www.capesoft.com  
Email sales@capesoft.com
Telephone +27 21 715 4000
Fax +27 21 715 2535
Post PO Box 511, Plumstead, 7801, Cape Town, South Africa
     

Buy Online
  Web  
 
 
 
 
     

How does it work?

Multi-Proj consists of 2 parts. Firstly it is an extension template that is added to the global area of your application. This template stores all the various project settings that are required to build the various versions of your APP. When your application is compiled a project for each version is created. A Batch file (.bat) is also created for each version, which contains all the necessary distribution commands.

The second part of Multi-Proj is the Multi-Proj Manager (MPM) . This is a separate utility which is able to drive the Clarion IDE (Find it in your Start | All Programs | Clarion 6 Accessories | MultiProj | Multi-Proj Manager). This is where you can group APPs and PRJs together to form Batches. Actually I should say that MPM groups them together for you - part of what the Extension does is link all the dependencies together - so adding just 1 PRJ file to your batch will add all the other PRJ and APP files that are required.

If the application is a DLL a template to use the DLL is automatically written for you. The template contains a global extension which will activate the DLL in another application. This activation includes prototyping all the functions exported by the DLL, and including the DLL in the new application's Project settings. A code template for each exported function is also included to simplify calling the functions.

To truly understand all the goodies that Multi-Proj offer, it is useful to understand how DLLs are normally created, maintained, and used, in Clarion. Doing things the hard way is the easiest way to see how Multi-Proj makes it easier. Of course you can skip all the pain and simply do it the easy way. If you want to dive right in, then a good place to go from here is the Tutorial. This walks you through all the steps of turning a single APP into a Multi-DLL product. It also shows you how to add Multi-Proj to a Multi-DLL product.


Multi-Proj Global Extension Options

General Tab

Project File Name : This is the name of the overall project containing all the separate versions. This is typically the same name as the APP.

Export File Structures : Exports file structures so they can be used in other APPs using this DLL. Note that all the usual Clarion settings and overrides still apply as they did before. (i.e. Generate All File Declarations, Export All File Declarations, Individual File Overrides etc).

Export Your Global Data : This exports the data variables, contained in the Global Data area (i.e. the Data button) so they can be used in other APPs using this DLL. It is recommended that you only export data from your data DLL, however you can export data from any other DLLs if you want to.

Export Template Global Data : The Clarion templates typically generate 3 global variables (GlobalRequest, GlobalResponse and VCRRequest) which are not visible in the Global Data area. These must only be exported by 1 DLL in your product - although more than 1 DLL can export YOUR global data. This should be set in your data DLL and not in any other DLLs.

Export ABC library : If your APP is based on the ABC library classes, then at least 1 DLL in your product (typically the Root DLL) needs to 'export' the ABC library. All the other DLLs and EXEs set the normal Clarion option "Generate Template Globals and ABCs as External"

Export Procedures in Module Order : When making a DLL it is important to always export the procedures in the same order. This makes your DLL more compatible with programs compiled with a previous version of your DLL. If you are adding Multi-Proj to an existing APP then this is one way to force the order of the procedures. For more information on compatibility see the section entitled DLL Backward Compatibility later in this document.

This APP has no _RD and _RU Files : This is for Legacy Template APPs only. Click this option on if this APP uses no Dictionary File Structures.

This APP has no _SF module : This module is usually generated by the Clarion Legacy Templates. However in some APPs it is not included. If your APP does not generate a _SF module then click this on.

This APP has no BC modules : This is for ABC Template APPs only. Click this option on if the APP has no BC modules. Typically the data dll will have BC modules, whereas the other apps will not.  If you get this option wrong (by ticking it on when you shouldn't) you will experience problem P1 as documented in the Multi-Proj Trouble-Shooting Guide.

Highest BC Number : This is only for ABC, and only needs to be filled in in the Data DLL.  The template will generate a number of modules named xxxxxBC0.CLW, xxxxxBC1.CLW and so on. The exact number of modules is dependant on your dictionary, and very hard to predict reliably, so Multi-Proj needs you to fill in the number here.  Note this can change as your dictionary grows. If you get this number wrong you will experience problem P2 as documented in the Multi-Proj Trouble-Shooting Guide.

Tip : Clarion counts them up from 0, to 9, then starts from A. You enter either the highest number, or if there are letters, then the highest letter.

Export OW Classes : This is for apps that have the Object Writer template included. If this item is ticked then the Object Writer classes will be exported, regardless of the EXPORT setting for these classes. If this option is not ticked then the classes will not be exported, again regardless of the EXPORT setting for those classes.

Only Export OW classes : If this option is ticked then only the class will be exported from the app. Use this option if you are making a DLL, which contains a class, but nothing else.

Suppress ABC Init : This suppresses the generation of all the ABC init code. Use this if your Object Writer class does not depend on any ABC classes.

This is app number : When making DLL's Multi-Proj supports a technique called Rebasing. This makes your apps load faster, and they're generally more "Windows friendly". This only applies to DLL's, Exe's and Lib's do not need to be rebased. For a detailed discussion about rebasing see ClarionMag ).  While figuring out all the various rebasing numbers can be confusing, Multi-Proj tries to simplify it for you.  Here's how it works;

Each DLL in your application has a "Big Picture" number. It doesn't really matter what the number is, but it's best to simply start with 1 and move upwards from there.  So the Allfiles app will be app number 1, then Procs DLL will be app number 2 and so on.

Each number is good for 1 meg of virtual memory. If your DLL is more than a meg big then skip a number in the next dll.  So if this data DLL was say 1.1 megs in size, then the Proces DLL would be app number 3.

Note for debugging: Leave the number set for the size of the non debug DLL's (i.e. compile the DLLs with DebugMode turned off to get the size you need to use). The extra size on the disk (when you compile with debugging turned on) is not loaded by windows. It is only used by debuggers, and analysis tools (like GPF Reporter and Profiler.)

Versions Tab

Versions : Click on this button to set up each version. If you are creating a multi-driver suite of apps, then each driver will need it's own Version.

Each Version has the following settings;

Title : This is the title on the list of versions. This title is only used for display purposes. A typical title might be "32-bit Stand-Alone, Debug Off, Version".

Set : If you are making a multi-dll, multi-driver, suite then you need to specify the SET that each version belongs to. Each different driver needs it's own SET name. For example, if you have a set of apps using the Topspeed driver, and this version uses the Topspeed driver then use a set name like TOPSPEED. It doesn't matter what the set name is (it could be TPS) so long as all the APPS in the suite use the same SET names.

Target Type : This is the target type of the version. Choose from EXE, LIB and DLL.

Target OS : This sets whether the version is 16 or 32-bit. (note 16 bit is retained for backward compatibility, but Multi-Proj no longer actively supports 16 bit programs).

Runtime Library : Set this to "Stand Alone" for compatibility with applications compiled with DLLs. Set this to "Local" for compatibility with applications compiled into a single EXE.

Debugging : Set this to On or Off.

Target Name : Enter the name of this version of the project. A PRJ, EXP and BAT file with this name will be created. Also a EXE, DLL and/or LIB file will be made with this name. Each version thus needs a different target name, and all the target names must be different to the Project File Name (as set above on the general tab). If you are compiling EXE's then each version needs to have a different name, although they can be renamed in the "Distribution" settings. For more information on naming standards and strategies see the section entitled DLL Naming Strategies later in this document.

Project Name : If the Project needs to have a different name to the target name then  you can enter the Project name here.  This is most often used when you are creating different versions of the same DLL, and the DLL's have the same (target) name.  In the case of a DLL (unlike an Exe) renaming after the fact doesn't work well.  But each version still needs a unique Project name, so you can enter that here.

Suppress this version for now : If you no longer want to generate a specific version, then tick this option on.

Resources : Add specific resources here which apply to this version. This would typically include other 3rd party libraries. Note that it is now possible for 3rd party products to integrate directly with Multi-Proj - saving you this step. For more information see the section entitled 3rd Party Support for Multi-Proj later in this document.

File Drivers : This lets you override the File Drivers that will be linked into this Version of the project. This is typically used when you're making use of the Driver Substitution facilities in Multi-Proj. (For more information on Driver Substitution read the Section below). If you add any drivers here, then you must add all the drivers here. None of the detected drivers, or drivers set on the All Versions Resources Tab will be included.

Defines : Add specific project defines here. This is typically used when you want to do conditional compiles. For more information on conditional compiles see the section entitled Conditional Compiles.

Distribution : This section allows you to copy files (for this particular version) from one place to another. Typically you might want to copy DLL, EXE or LIB files.

Resources Tab

File Drivers : Multi-Proj should detect all the file drivers used by the project. If it misses one (or more) out then you can enter them here. Enter the Driver name, not the library name (e.g. TOPSPEED for Topspeed driver etc.)

Force : If you are generating the Prj in one version of Clarion, but planning to actually compile it in another, then set the actual compile version of Clarion here. This makes sure that the correct file driver libraries are inserted ready for compiling.  This feature is mostly used by Clarion 3rd Party suppliers to compile their DLL's in various Clarion versions. 

Common Resources : These are resources that will be used by all the versions of your APP. These are typically graphic files, like ICOs, BMPs or GIFs.

External Source : This is for external source files that may be used in your application. For example if you make use of the resize support in Clarion 2 then you will need to add the ResCode.Clw file here. To see what other external sources your application uses, check out the External Source Section of your APPs Project settings.

Enable Override Drivers : Turn this on if you want to enable the Override Driver support. For more information on overriding drivers see Driver Substitution later in this document.

OverrideDriverPossibilites : This allows you to create one, or more, Driver override Possibilities. Note this is not doing the overriding - merely creating the possibility of an override. For each possibility you need to set;

Template Tab

Template Set Name : If this DLL is to be part of a larger Template SET then enter the template set name here. This is normally used when this is not a generic DLL, but rather a DLL specific to an application. By creating one SET for all the specific product related DLLs, the templates are grouped better in the template registry. This name would probably be the name of the product. If you are creating a generic DLL which will be used in many different APPs then leave this name blank.

NB - you will need to register this template after it's generated the first time.

Template File Name : This name is typically the same name as the APP file itself. If this DLL is not part of a Template SET then this file should have the extension TPL. If it is part of a bigger SET then it should have a .TPW extension. This template will include a Global Extension Template (for activating this DLL in other APPs) and a code template for each Exported Function in the template.

Note that if this APP is an EXE then it makes no sense to have a Template - so leave this entry blank in that case.

Don't Generate Code Templates : Click this on to only generate the Global Extension, and not the Code templates. You would typically do this if you are creating the Code Templates yourself (stored in some other TPW file in the same SET).

Includes : If you are wise enough to add your own, hand-written template files to this template set, then add a list of your own TPW files here.

Don't generate Dependancy defines : Part of what Multi-Proj does is generate special defines into the generated PRJ's so that the Multi-Proj Manager can figure out which apps are dependant on which other apps. If you wish to suppress this feature then you can tick this option on.

Advanced Tab

MsSql : Real becomes Sreal: Tick this option on if you are using driver substitution, to MsSql, and you are not using FM3. This option automatically converts any REAL fields in your dict, into SREAL fields when generating the MsSql file declaration. It needs to do this because Clarion does not correctly convert REALS to FLOATS when the file is created. (If you are using FM3 then you can leave this switch off, as FM3 creates the table correctly.)

Bulk Generating and Compiling

Multi-Proj ships with a stand-alone utility called the CapeSoft Multi-Proj Manager - or more easily known as MPM. This small application lets you group applications together for batch generation, compilation & distribution. Using DDE it talks to the Clarion IDE and instructs on what to generate and compile.

You can run the Multi-Proj Manager by going to the Accessories Menu in the Clarion IDE, and selecting Multi-Proj Manager. For a run through of using the MPM see the Tutorial. Also note the use of the Online Help available throughout the product - simply by Right-Clicking on any of the controls and choosing What's This. There is also the Multi-Proj Manager Complete Documentation.

In addition to the pretty obvious features of MPM it's worth pointing out the following features:

On the Tools menu, Template Utility option : This allows you to run a Template Utility on a number of APPs in a Batch. This is very useful for analytical, or documentation tools such as Sable Software's App-Ref tool.

On the Tools menu, Options item : This window contains some options which control how MPM behaves.

Using a Multi-Proj DLL in another application

Because Multi-Proj writes a template for you, it's quite easy to use the functions exported from your DLL in your other APPs.

1. When you first write a new DLL, you'll have to register the new template that Multi-Proj makes for you. Actually if the new template is part of a Template Set then the Set has to be registered. Once the Set has been registered it does not need to be re-registered every time you add a new DLL to it. This is one of the advantages of using Template Sets.

The name of the Template Set is what you set on the Template tab of the Multi-Proj extension. Or if there is no Template Set entered there, then use the Template File Name. (If there's also no Template File Name then there's no template!)  You only need to register the template once - when you change your DLL the Template, and the Template Registry are updated automatically. 

To register a template go to the Setup menu (in the Clarion IDE) , to Template Registry option and click on the Register button.
2. The first time you use the DLL in another application, go to the Global Extensions area. Then include the Activate_XXX global extension template. (XXX is the name of your library). This extension adds the DLL to your current APP, and prototypes all the exported functions, and data, for you.

If you are building a multi-driver system then you will need to set the Driver Set that the app will belong to. In other words when you compile the application itself, which driver do you want it to use. The template will offer you a drop-down of the various sets that are available for the DLL you are activating.

3. When ever you want to use one of the functions in the DLL, then you can either go to an embed point, and type the call in there, or you can make use of one of the Code templates that Multi-Proj generated for you.  There is a code template for each generated function which will prompt you with the parameters required, and the syntax for the function.

External Functions in the Application Tree

It's often useful to have some of your External functions present on the Tree in the IDE. Clarion does this for you when you use one of the template ways of one procedure calling another. For example if you call a procedure, using the template, from a Frame or Menu, then that procedure appears, as a To-Do, under the Frame in the application tree.

When you're dealing with multiple DLL's you would usually go ahead and define the procedure as being an ExternalDLL - and create a module, in your Tree, for the DLL. However there is a problem with this approach. If you do it this way, the name of the DLL is entrenched in the APP file. This may seem like a good thing, but it's not. It makes it impossible to create different versions of this App (which might use different versions of that DLL) in a smooth and easy manner.

One way (and the way used in earlier Multi-Proj versions) was to simply not allow Procedures to be created in this way. There is however a simple work-around which lets you have your cake, and eat it.

Multi-Proj includes two simple templates which essentially allow procedures to be defined as Externals and be visible in the tree, and yet not complicate our multiple version approach. It's a bit of kludge, but hey, it works.

Firstly create the External Module - using not one of the regular external modules, but the one offered by the Multi-Proj template. ( i.e. Open the App, Application menu, Insert Module, and select the Multi-Proj External Module.) This Module MUST be called External.Ico and you must make the Map Include file set to Empty.Clw . Then you can click on each To-Do in turn, and make the Multi-Proj External Procedures. As you do this make sure the Module name is External.Ico - select it from the list if necessary.

But hold on - you say - What's this about an Icon. Well the truth is, External.Ico (in your Tree) is NOT an icon. It's simply a convenient name which the IDE is happy with. It's necessary to go with the strange name to fool the Linker a bit later on. Unfortunately in this case the IDE is too smart, and insists on adding whatever name we use to the Project ( the one built into your application). Usually at this point it would be a LIB file - which is what we're trying to avoid. By using the name of an Icon ( which does actually exist - it's shipped with Multi-Proj) - the linker is happy.

The reason we use the Empty.Clw statement in the Map is because all of these procedures are going to be prototyped by their respective Multi-Proj generated templates. If we let Clarion do it's normal thing we'd get an 'Indistinguishable Prototype' error. So again to override Clarion's cleverness we use this simple override.

Tips

1. If you are creating a DLL / Lib combination then set the APP itself to be a DLL. Then click the Export Function switch for those procedures you want to export.
2. If your program gets link errors when trying to compile the project, but the application itself compiles ok, then check the "Project" settings of the APP. Most likely you have omitted a resource in either your Version Resources, or Common Resources.
3. If you want maximum value from the Code template then use the long form of prototyping when you prototype your functions in the DLL. The prototype for the procedure is set on the Procedure properties window.   Normally you only put the parameter types in the Prototype e.g. (LONG, LONG, STRING) . However you can also put the variable names here.  For example (LONG FromDate, LONG ToDate, STRING Holiday)
4.
If you are using FM3, and you are using Multi-Proj to create multiple driver versions of your app, then you need to handle the fact that each driver version of your file represents a different file version number (as far as FM3 is concerned). To do this;

in your data dll

global embed point, called "program setup"
priority 10
put
  compile('***',MsSQLDriver=1)
  ds_VersionModifier = 1000
  ***
 
if you had a third driver, say oracle, then you'd also add
 
  compile('***',OracleDriver=1)
  ds_VersionModifier = 2000
  ***

 
and so on.

 

5. If you are struggling to use the Multi-Proj Manager, because of DDE problems, then try making a shortcut to the Mp.Exe on your desktop. Running it from here, rather than from inside the IDE (Accessories menu) seems to work better on some machines.
6. If you are using Clarion 5, make sure you have downloaded the necessary patch file here.

List of Errors

Compile and Link Errors

Make error: File "<filename>.exp" not found: The name in the Target filename in Project Properties is not the same as the Target name in the Multi-Proj Global Extension - Version Tab. The target type in the Multi-Proj Global Extension does not match the target type in the Project Properties. If you are building a DLL make sure they are both set to DLL.

Execute of <filename>.DLL failed, File not found: Make sure in the Project Properties, that you haven't put the Target Name in the Programs to Execute section by mistake.

Link Error: Unresolved External NetDUNRename (and about 90 others): This is caused if this Application is a Data DLL, and NetTalk is installed on your system, and neither the Activate, nor Suppress NetTalk extensions are in this app.  If you intend to use NetTalk then add the Activate NetTalk Global Extension to the application, otherwise add the Suppress NetTalk Global Extension.

Link Error: Unresolved External <$CUSTOMER> in <filename>.obj: This may happen if you have not included all the Global Templates for all the DLL's in your project. You should have a Global Template for each DLL that this application is dependant on, plus your template set name Global Template. (If this occurred when you were doing the tutorial and you had not done the first part of the tutorial, then you probably chose to Generate All, instead of the 'Just This File' Generate option. If you are not working through the whole tutorial and are just doing the Multi-Proj Manager tutorial, then re-install Multi-Proj to restore the original tutorial files.

Link Error: Unresolved External ~<iconfilename> in <filename>.obj: This will happen if you've put the tilde character in front of icon files in your browse icons tab. You need to remove the tilde characters from the front of the icon filenames that you have used in your brwose icons. These are icons are included in your project and the icon used will be the one included in the project. Only icons used in handcode require a tilde to use the icon included in the poject.

Syntax error: Indistinguishable new prototype: <procedure name>: You may have declared your procedure to be an ABC External type when it should be a Multi-Proj ExternalProcedure.

Link Error: Unresolved External: Possible causes:

  1. If you are using 3rdparty products that are adding items to your Application's project and are not MultiProj compatible, then they will be not be informing Multi-Proj about those LIBs.
  2. You have not informed MultiProj what the highest BC module is (that is generated by your application).
  3. There are some file drivers/external resources that have been added manually to your app's project, that MultiProj does not know about, and is not adding to the Project.
  4. You have added a function to one of your DLLs, but the IDE is not automatically updating your template chain. (See the FAQs on overcoming this issue)

How to resolve this:

$VCRRequest is unresolved for Export: This should only happen in old version of Clarion 2, before this variable was introduced. To fix this error, go to the Global Embeds, in the "Global Data" embed point add 

VCRRequest long

Missing Global Variable Declaration: GLO:<Filename>_Name: You are using Driver Substitution and  FM3, but you have not checked the "Create global variables for file names" in the Multi-Proj global extension template.

You have not allocated a unique template name in the Template tab of the Multiproj Template.

My Compiler GPFs since breaking my app into DLLs.

  1. Are the first 5 letters of _every_ app unique? We've seen problems where the first 5 are common and this leads to generated source from one app ending up in another.
  2. Does it GPF at the same place? ie could it be code related? We've seen "bad" code sometimes GPF the compiler.
  3. Clean out obj32 and obj32\release from time to time, that can help if you got a bad obj file.
  4. After a gpf go to the windows task manager and remove any process called NTVDM or C6*

Driver Substitution

Driver Substitution (DS) is a Multi-Proj Advanced Feature and may not be relevant to your situation. DS is useful however if you are changing from one Driver to another - or you wish to support multiple drivers in your application. For example if you have an existing application using the TOPSPEED driver, but you wish to also have an MSSQL version, then Multi-Proj will allow you to do this.

One point to note here however is that Multi-Proj does not optimize your code at all for the drivers. There are some differences, internally, between ISAM (Flat File) drivers like TOPSPEED and SQL drivers like MSSQL. In time you may want to optimize parts of your code for the actual driver. At this stage Multi-Proj merely performs the driver substitution. It is however possible (using Conditional Compiles) to optimize your code for both drivers. That will be discussed in a moment.

Note: Before proceeding with implementing driver subsitution, you must make your dictionary SQL compliant (see http://www.capesoft.com/docs/fm3/fm3sql.htm#Convert). It is highly recommended that you use FM3 to manage your data conversion, as doing this manually will be very tedious (www.capesoft.com/accessories/fm3sp.htm)

The Mechanics

Adding Driver Substitution to your application is a 2 part process.

1. First on the Multi-Proj extension, on the Resources Tab, Click Enable Driver Substitution ON. Then click on the Override Driver Possibilities button. The idea here is to define which drivers might be overridden. In our example (of having TOPSPEED and MSSQL versions) we will override the TOPSPEED driver with MSSQL in some versions, and in other versions we won't. We'll get to the versions in a moment - for now we're just defining the possibilities.

With each possibility you'll need to enter a Conditional Define. This is basically an identifier or an equate. This equate will be defined for you. When the equate is 1 then the driver will be substituted, when it's 0 it won't. You'll see how the equate is set in a moment - for now though it's necessary just to create the name. For the example I'm going to call it UseMsSql.

You'll also need to set the From and To drivers.  If the SQL backend restricts the number of characters (for example old versions of MySQL has a 12 character limit) then enter that.  In the case of most SQL backends you'll need to enter a database prefix. For MsSql this is most likely to be dbo. (including the .) but this does depend on your database.

In the data DLL you'll also need to enter the Owner (usually a variable that contains the database connection string) and optionally a Send string. 

2. The second part of the process is creating the actual MSSql version. You do this by creating a Version in the normal way. There are 2 things you need to do here differently to a normal version. Firstly go to the Defines Tab (of the version) and enter your Conditional Define, followed by =>1. for example;

Then go to the Resources Tab (still in the same Version) and click on the Other File Drivers button. Here you'll need to make sure that your Export Memos is unchecked for SQL versions.

Note (for FM3 users):

The Internals

If you look in your main module for your App you'll see that Multi-Proj generates the file structures multiple times - once for each possible substitution, and once for the actual dictionary set. However ONLY 1 set of file structures is actually Compiled into your application. By using Conditional Compiles, and the Conditional Define, Multi-Proj allows for the different versions of your program.

Multi-Proj may have to change the file structure slightly in order to accommodate the specifics of each driver. For example Topspeed files support the MEMO data type - but MSSQL doesn't. So for MSSQL memo fields are converted to CStrings. In addition some of the File attributes are not supported by all drivers, so where necessary they are removed (for example MSSQL doesn't support RECLAIM).

Other Issues

Your file structures needs to contain only data types which are valid in both drivers. See the Advanced tab for specific field overrides that Multi-Proj can do for you.

Overriding Driver Substitution for individual files

If you'd like to keep specific data files as a type (not being influenced by the Driver Substitution), then you can add the following File UserOption to your dictionary file declaration:

FIXDRIVER            <DriverType>

Open your dictionary and right-click on the file that needs to be fixed, go to the options tab and add a User option as follows:

Note, you must set the Value to what you want it to be (typically the original FileDriver itself).

Handling Dynamic Indexes in your Dictionary

The easiest option is to remove the dynamic Index(es) - although this is not always possible to continue supporting your TPS version. If you cannot delete the dynamic index, then you need to do the following in the Key User Options for that particular index:

Basically, MultiProj needs to force a field name into the Index, so that a non-dynamic index will be created in the SQL project. The above FieldName option is the name of a field in that table.

Browse Filtering in your app

In your browses, you may have used different keys in filters for the browse. When using SQL, you need to use the primary key - or alternatively add the primary key component field to the key that you are using.

3rd Party support for Multi-Proj

One of the features in Multi-Proj is the addition of a number of Embed points. These allow other 3rd party products to interact with Multi-Proj, which saves you a lot of time and effort. The following section deals with these features, and is directed primarily at Template Authors. If you do not write templates then you can safely ignore this section. However if you're a user of other 3rd party products, and the product is not MP compatible, then you might want to direct them to this document so they can add compatibility.

The primary goal of the compatibility features is to reduce the amount of work required by the User to add resources to the application. In the template language this is taken care of using the #Project command. Unfortunately there is no way to Read the contents back from #Project - and indeed in certain cases this would be insufficient anyway. In order for you, the Template Writer, to afford the user maximum computability between your product and Multi-Proj you need to add some extra code in addition to each of your #Project statements. Lets look at each type of resource in turn;

Graphics Resources

These are files such as BMP, WMF, GIF, ICO ,CUR and so on. These files are "version independent" and so are added to a single Embed point - called
%mpRscAll
If your template has a statement like
#Project('Cool.Ico')
then you need to add the following to your template
#AT(%mpRscAll)
%#pragma link ("Cool.Ico")
#ENDAT

Source Code Resources

These are CLW files which your template might use, but which are not added to the Application Tree.Your template code might typically look like this;
#Project('Tag.Clw')
then you need to add the following to your template
#AT(%mpCompileAll)
%#compile "Tag.Clw"
#ENDAT

Note that the above embed point is used for Source files which are included Regardless of the Target (16 or 32-bit) or the Runtime Library (i.e. Stand-Alone or Local). There are also embed points which are only used in specific cases - i.e. if the your external source file is dependant on the Runtime Library, or the Target then you can use the following embed points;
#AT(%mpCompile) #! 16-bit DLL
#AT(%mpCompileX) #! 32-bit DLL
#AT(%mpCompileL) #! 16-bit Local
#AT(%mpCompileXL) #! 32-bit Local

LIB and OBJ Resources

These resources are almost always dependant on the Target, and Runtime library of the program being compiled. Your code will probably look something like;
#IF(%ApplicationLocalLibrary)
#IF(%Target32)
#PROJECT('CL5Fm232.lib')
#ELSE
#PROJECT('CL5Fm216.Lib')
#ENDIF
#ELSE
#IF(%Target32)
#PROJECT('CW5Fm232.Lib')
#ELSE
#PROJECT('CW5Fm216.Lib')
#ENDIF
#ENDIF

In this case there are 4 separate embeds you can use, one for each case. A Multi-Proj equivalent of the above would look like this;
#AT(%mpLibXL)
%#pragma link ("CL5Fm216.Lib")
#ENDAT
#AT(%mpLibL)
%#pragma link ("CL5Fm216.Lib")
#ENDAT
#AT(%mpLibX)
%#pragma link ("CW5Fm216.Lib")
#ENDAT
#AT(%mpLib)
%#pragma link ("CW5Fm216.Lib")
#ENDAT

Project Defines

These are template driven defines that are placed in the Project Defines section. Typically your code might look like this:

#pdefine('MyDefine=>1')

Leave this define as is for non-Multi-Proj users, but for Multi-Proj users, add the following:

#AT(%mpDefineAll)
%#pragma define(MyDefine=>1)
#endat

Global Data

Many times you may have global data that you are wanting to export to your other programs. This can be done by simply writing these into the EXP file as follows:

#AT(%MultiProjInsideExports)
  #for(%MyGlobalData)
#!Code in here
  #ENDFOR
#endat

For the 'code in here' check out the %DataExport group in the MultiProj template file for details on how to do this (the multiprj.tpl file is located in the 3rdparty\template directory of your Clarion install). You can also check out how MultiProj exports the data in the exp file.

DLL Backward Compatibility

One topic worth discussing briefly is that of making sure your DLLs are backwards compatible. What I mean by this is that you are able to ship a more recent version of your DLL, into an existing client, without there being any side effects. This is a very powerful approach because it allows you to distribute bug fixes, and minor updates, of your product in pieces, rather than requiring a whole new install.

The key to this compatibility issue is the items which are Exported from the DLL. This can get quite complicated, so I'm going to stick to the basics here. The items exported are stored in the EXP file. If new stuff is ONLY added to the bottom of the EXP file, then the DLL will be forwards compatible. In other words the new DLL will work with programs compiled earlier.

However, the stuff in the export file is stored by Number, not by Name, and it is usually listed as first data, then procedures, then classes and so on. Thus if you add data to the DLL, all the procedures will get a different number.

For this reason it's a good idea to restrict the exporting of data to the Data DLL. All the other DLLs should export only Procedures. Then items added to the DLL will be at the bottom of the EXP file, and the DLLs will be completely forwards compatible.

Conditional Compiles

In Clarion it is possible to conditionally compile code, depending on some settings in the PRJ file. Remember the goal of Multi-Proj is to allow you to compile multiple versions of the same APP - from the same source files. This implies that the source files must contain all the possible flavors of the code. However, of course, only one flavor must be compiled in any given situation.

For Example : If you are using any Windows API calls, then in all probability these calls are slightly different in 16-bit and 32-bit. So a 16-bit DLL needs to compile slightly different code to a 32-bit DLL. this is an example of where using a Conditional Compile is very useful. To use the GetWindowsDirectory call you would need to do the following in the Global Map;

Module ('Windows')
COMPILE('***',_WIDTH32_=0)
  GetWindowsDirectory(*CSTRING,USHORT),USHORT,PASCAL,RAW,name('GetWindowsDirectory')
***
COMPILE('***',_WIDTH32_=1)
  GetWindowsDirectory(*CSTRING,USHORT),USHORT,PASCAL,RAW,name('GetWindowsDirectoryA')
***
End !Module


In the above example we make use of the _Width32_ define (this is a built in define) to determine if the DLL is compiling in 16 or 32-bits.

This approach is however very useful in other circumstances. For example, say you wanted to create a debug version of your program, and a non debug version. Then you could add the following code to your APP;

COMPILE('***',_Debg_=1)
  stop('The variable x = ' & x & ' here ')
***


Or you might want to create a message screen for non-registered versions, like this;

COMPILE('***',_Demo_=1)
  Message('Come on! Please send me money!!')
***


One useful tip is that Defines used in this way are automatically assumed to be 0 if they don't exist. Thus you only have to add them to versions when they must be set to something other than 0. To add a define to a version, go to the Multi-Proj extension, go to the specific version, go to the defines tab, and simply set the Define to 1 there. For example;
_Demo_=>1
Notice the somewhat unusual => sign (which means equals).

Also remember that _Width32_ is set for you in 32-bit compiles.

If you are doing a multi-driver system and you want to add code for a specific driver, then you can use the Conditional Define that you created on the OverRide Driver Possibilities list.  For example if you used UseMsSqlDriver  then you can encapsulate some code in a conditional compile. For example;

COMPILE('***',UseMsSqlDriver )
  myview{prop:sql} = 'Select * From Customers'
***

This code will then only be executed when the MSSql driver is being used.


DLL Naming Strategies

It is useful to follow a strategy when naming DLLs. You can use whatever strategy you like - some common strategies are listed here for your convenience. Obviously your naming strategy will depend on you specific requirements.

Clarion style

This was introduced with Clarion 4, and is still used with Clarion 5, 5.5 and 6.

CnaaaXL.DLL

Clarion Old style

This is the Style used with Clarion 2.

Ct2aaann.DLL

FAQs

I'm getting compile errors in my Project

1.1. I've added a new function to one of my DLLs, but when I try to use it, it says 'unresolved external' in the other application.
1.2. When I run my MultiProj compiled application, the Application icon is not the same.


1.1. I've added a new function to one of my DLLs, but when I try to use it, it says 'unresolved external' in the other application.

Answer: You probably have not setup Clarion to re-register your templates, so your application does not know about the new function added to the DLL. Set this up in the Clarion IDE as follows:


1.2. When I run my MultiProj compiled application, the Application icon is not the same.

Answer: You need to tell MultiProj what your application icon is in the Resources tab  of the MultiProj template (you'll find an Application Icon entry field on that tab).

Copyright and License

Multi-Proj and Multi-Proj Manager are copyrighted © 2004 by CapeSoft Software (Pty) Ltd. All rights are reserved. CapeSoft Software (Pty) Ltd trades as CapeSoft.

This product, and all the files contained therein, is copyrighted by CapeSoft Software (Pty) Ltd.

Each developer needs his own license to use Multi-Proj. (Need to buy more licenses?)

This product is provided as-is. CapeSoft Software (Pty) Ltd, employees of CapeSoft, and Dealers of CapeSoft products, explicitly accept no liability for any loss or damages which occur from using this package. Use of this package constitutes agreement with this license. This package is used entirely at your own risk.

For each copy of Multi-Proj purchased you are entitled to use it with one copy of Soft Velocity's Clarion for Windows product. You may not in any way distribute the Multi-Proj template or Multi-Proj Manager EXE. You may not derive other templates from the Multi-Proj template. Templates written by Multi-Proj are your property and can be distributed as you wish.


Version History

2.75 Released 18 July 2007 2.74 Released 12 June 2007 2.70 Released 12 April 2007 2.66 Released 8 May 2006 2.64 Released 6 Aug 2004

2.63 Released 12 Jan 2004

[End of document]