Author: Tomas Rutkauskas
I have a package which contains a form and some units. I want to be able to load
that form into a main application but I have no idea how to do it does anyone have
some example code I can look at?
Answer:
There are two ways to use packages: statically bound or dynamically loaded. This is
similar to DLLs. To bind a package statically to your project you name it in the
projects package list and build the project with run-time packages.
To use something from the package you simply add the unit that contains the
something to a uses clause as if it were part of the project. The linker takes care
of making sure the unit is not compiled into the project but linked in from the
package at run-time. In this scenario the code using the package is completely
unaware that the stuff it uses comes from a package.
Dynamically loaded packages are somewhat more complex to use. The following is an
excerpt from an older reply on how to put MDI children into packages. Note that you
need to build the host app with run-time packages, you just use only the standard
set of packages, do not name the packages you want to load dynamically in the
package list.
Quote:
If you load them dynamically via LoadPackage the main program typically gets a list
of available child form packages from somewhere, e.g. from an INI file, a registry
key, or simply by scanning a folder at a known location for BPL files. Each package
is required to export a set of functions with known names (perhaps only one). You
export functions from a package the same way you do it from a DLL, via an exports
clause. And you get these entry points from your main program also the same way you
do it for DLLs, via GetProcAddress. So each child form package would export a
function
1 2 function CreateChild: TForm;
The main app can now create child forms just by calling this function for each
childform package. Whether it uses the returned reference is up to the program, it
can get references to the child forms from mainform.MDIChildren if it needs them.
Each child form in turn is required to implement a specific interface which the
main form can use to communicate with it. This interface can be message-based, or
it can be an actual Interface (non-COM) which the main form can obtain by sending a
specific user message to the child form. This way the main form needs to know no
details about the child forms, so has no need to Use the child forms unit.
If you don't load the packages dynamically you can still remove the dependence on the child form units completely. In this case the CreateChild method would be something the package exports in a unit (one unit per package, it may contain only this one function) and the main form would Use this unit from each of the packages. This is of course not very maintenance-friendly, there are other ways to manage this, e.g. by using a central registration mechanism (implemented in a common package) into which each of the child packages can register its CreateChild function together with the package name. The main form could then ask this registry to create a child for a given package. If the main form reads the list of packages from some file this would make your package set extensible without requiring any change to the main form when you add a new one.