gin
PackageModule := LoadPackage(''''Package1.bpl'''');
if PackageModule <> 0 then
begin
AClass := GetClass(''''TForm2'''');
if AClass <> nil then
with TComponentClass(AClass).Create(Application)
as TCustomForm do
begin
ShowModal;
Free;
end;
UnloadPackage(PackageModule);
end;
end;
Unfortunately that''''s not the end of it.
The problem is that the GetClass function requires the class to be registered before the function can find it. Usually form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered when the form is loaded. But the form isn''''t loaded yet. So where should we register the class? The answer: in the package. Each unit in the package is initialized when the package is loaded and finalized when the package is unloaded.
Let''''s return to our example and make a few changes:
- Double-click on "Package1.bpl" in the project manager; this will activate the package editor.
- Click on the + symbol next to "Unit2" in the "Contains" section. This will expand the unit tree.
- Double-click on "Unit2.pas" to activate the unit''''s source code.
- Scroll down to the end of the file and add an initialization section.
- Register the form''''s class using the RegisterClass procedure:
RegisterClass(TForm2);
- Add a finalization section.
- Un-register the form''''s class using the UnRegisterClass procedure:
UnRegisterClass(TForm2);
- Finally, save and compile the package.
Now we can safely run the "Project1" application - it will function just as before, but with the added benefit of being able to load the package when you want to.
Finally
Make sure you compile any project that uses packages (static or dynamic) with runtime packages turned on: "Project | Options | Packages | Build with runtime packages."
You must be careful that when you unload a package you destroy any objects using those classes and un-register any classes that were registered.
This procedure may help: procedure DoUnloadPackage(Module: HModule);
var
i: Integer;
M: TMemoryBasicInformation;
begin
{ Make sure there aren''''t any instances of any
of the classes from Module instantiated, if
so then free them. (This assumes that the
classes are owned by the application) }
for i := Application.ComponentCount - 1 downto 0 do
begin
VirtualQuery(
GetClass(Application.Components[i].ClassName),
M, SizeOf(M));
if (Module = 0) or
(HMODULE(M.AllocationBase) = Module) then
Application.Components[i].Free;
end;
UnRegisterModuleClasses(Module);
UnLoadPackage(Module);
end;
An application requires "knowledge" of the registered class names prior to loading the package. One way to improve this would be to create a registration mechanism to inform the application of all the class names registered by the package.
PRACTICAL EXAMPLES
Using multiple packages: Packages do not support cyclic referencing. That is, a unit cannot use another unit that already uses it. This makes it rather difficult to set value in the calling form.
The answer lies in using additional packages the both the calling object and the packaged object use. How else do you think we then set up "Application" as the owner to all our forms? The variable "Application" resides in Forms.pas, which in turn is packaged into VCL50.bpl. You will notice that your application compiles with VCL50 and your package requires VCL50.
We can use this methodology for our own package design.
In our third example we will design an application that shows customer information and optionally (dynamic load) shows customer orders.
Where can we start? Well, like all database applications, we will need connectivity. So we will create a main data module that will contain a TDataBase connection. Then we will place this data module in a package (I''''ll call it cst_main).
Now in our application we will create the customer form and use the DataModuleMain that we will statically link into our application by setting the compile with packages to include VCL50 and cst_main.
We then create a new package (cst_ordr) that will contain our customer orders form and data module and require our cst_main. We will then write code in our main application to dynamically load this package. Since the main data module is already loaded when the dynamic package gets loaded, it will use the application''''s instance of the main data module.
This is a schematic of how our application will function:
Using swappable packages: Another example of package usage is the creation of swappable packages. One doesn''''t even need to use dynamically loaded packages for this! Let us assume we have the need to distribute a trail version of our application with an expiry or trial period. How would we go about doing this?
First we would create a "splash" form -- something that would show a graphic and the word "Trial" on it that will display when the application starts up. Then we would create an "about" form that would display information about our application. Lastly, we would create a function that would be called at some time to test for expiry. Then we would bundle these two forms and the function into a package and deploy it with our trial version.
For our "paid for" version we would also create "splash" and "about" forms, remembering to put the same class names (even the case), and the test function (this one doing nothing) into a package with the same name as our trial package.
What, may you ask, will this help? Well -- just think of it -- we could distribute a trial version publicly. Then when a client purchases the application we only need to send the non-trial package. This will shrink our distribution process to only one complete install and a registered package upgrade.
Packages open up many doors in the Delphi and C++Builder development world. They enable a true modular design without the overhead of passing window handles, callbacks, and other technologies in DLLs. This in turn will shorten our development cycle for modular programming. All we need do is let Delphi''''s package technology do the work for us.
Download the example source code of this paper here.
By Vino Rodrigues vinorodrigues@yahoo.com
上一页 [1] [2] [办公软件]PowerPoint模板使用经验之谈 [办公软件]教你在Powerpoint中设置页眉页脚 [办公软件]在Powerpoint中如何插入Flash动画 [办公软件]如何在Powerpoint 中(实现)输入上标、下标 [办公软件]如何在PowerPoint同一张幻灯片中显示大量文字 [办公软件]这样来修改PowerPoint超级链接的文字颜色 [办公软件]PowerPoint小小操作技巧,让您工作更轻松 [办公软件]如何在office(PowerPoint,Word,Excel)中制作带圈的… [办公软件]保留PowerPoint超链接,但是取消超链接的下划线 [办公软件]挖掘PowerPoint图片自动压缩功能在不失真的情况下…
|