转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
Dynamic packages in Delphi         ★★★★

Dynamic packages in Delphi

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1448 更新时间:2009/4/23 18:40:01
Dynamic packages in Delphi

Abstract:A paper on how to create and use dynamic packages in Delphi. By Vino Rodrigues.

Any discussion of advanced package use in Delphi must raise the question: Why use packages at all?

Design-time packages simplify the tasks of distributing and installing custom components. Runtime packages, which are optional, offer several advantages over conventional programming. By compiling reused code into a runtime library, you can share it among applications. For example, all of your applications -- including Delphi itself -- can access standard components through packages. Since the applications don''''t have separate copies of the component library bound into their executables, the executables are much smaller-saving both system resources and hard disk storage. Moreover, packages allow faster compilation because only code unique to the application is compiled with each build.

Packages are even better when they are used dynamically. Packages offer a modular library approach to developing applications. At time those modules may become an optional entity of your application. Take for example an accounting system with an optional HR module. For some installations you will need to install just the base application -- for others you will install both the base application and the HR module. This level of modularization can be easily achieved by just including the optional package to the install base. In the past this was usually achieved with dynamically loaded DLLs, but with Delphi''''s package technology it is easy to make your modular classes part and parcel of your application. Classes created from packages become application-owned and thus can interact with your application classes.

Runtime packages and your application

Many developers think that Delphi packages are a place to put component -- but a package can (and should) also be used to modularize an application.

To show how to use packages to modularize your application we will create an example:

  1. Create a new Delphi application with 2 forms: Form1 and Form2.
  2. Remove Form2 from the auto-created form list in the Project | Options | Forms menu dialog.
  3. Drop a button on Form1 and add the following code to the OnClick event handler:
    with TForm2.Create(Application) do
    begin
      ShowModal;
      Free;
    end;
  4. Remember to add Unit2 to Unit1''''s uses clause.
  5. Save and run the project.

We have created a simple application that shows a form with a button that shows another form when it is clicked.

But what if we wanted to create Form2 in a reusable module?

The answer is -- PACKAGES!

To create a package for Form2 we will:

  1. Open the project manager (View | Project Manager)
  2. Right-click on the Project Group and select "Add New Project..."
  3. Select "Package" from the "New" items list.
  4. You should now see the Package editor.
  5. Select the "Contains" item and press the "Add" button.
  6. Now use the "Browse..." button to select "Unit2.pas."
  7. The package should now contain the unit "Unit2.pas."
  8. Now save and compile the package.

The package is now complete. You should have a file called "package1.bpl" in your Projects BPL directory. (The BPL is the Borland Package Library; the DCP is the Delphi Compiled Package -- sort of like the DCU of a PAS file.)

That''''s all that need to be done to the package. We now need to compile the original application with the package option switched on.

  1. Select the project "Project1.exe" from the Project Manager by double-clicking on it.
  2. Right-click and select "Options..." (You can also select Project | Options... from the menu.
  3. Select the "Packages" tab.
  4. Check the "Build with runtime packages" check box.
  5. Edit the edit-box in the "Runtime packages" section to read: "Vcl50;Package1" and OK the options.  
  6. NOTE: Do not remove Unit2 from the application.
  7. Save and run the application.

The application will run and behave just like before -- the difference can be seen in the file size. Project1.exe is now only 14K as apposed to the original 293K. If you use a resource explorer to view the contents of the EXE and the BPL you will find that both the DFM and the code for Form2 now reside in the package.

Delphi achieves this by statically linking in the package at compile time. (That''''s why you shouldn''''t remove the unit from the EXE project.)

Just think of what can be achieved by doing this: One could create data modules in packages and quickly modify their source and only distribute the new package when our data-access rules have changed, like when we move from BDE based connectivity to ADO. Or, we could create a from that show''''s a "this option is not available in this version" message in one package, and then a similarly named form that has functionality in a same-named package. We will then have a "Pro" and "Enterprise" version of our product without much effort.

Dynamic load and unload of packages

Statically linked DLLs and BPLs work fine in most cases, but what if we decide not to deploy the BPL? We would get a "The dynamic link library Package1.bpl could not be found in the specified path..." error and our application would stop functioning. Or what if, in our modular application, we wanted to have numerous plug-in like modules?

We need a way to dynamically link to the BPL at runtime.

With DLLs this is a simple process of using the LoadLibrary function.

function LoadLibrary(
  lpLibFileName: PChar): HMODULE; stdcall;

Once the DLL is loaded we can call exported functions and procedures within the DLL by using the GetProcAddress function.

function GetProcAddress(hModule: HMODULE;
  lpProcName: LPCSTR): FARPROC; stdcall;

We finally unload the dll by using the FreeLibrary function.

function FreeLibrary(hLibModule: HMODULE): BOOL;
  stdcall;

In this example we will dynamically load Microsoft''''s HtmlHelp library:

function TForm1.ApplicationEvents1Help(
  Command: Word; Data: Integer;
  var CallHelp: Boolean): Boolean;
type
  TFNHtmlHelpA = function(hwndCaller: HWND;
    pszFile: PAnsiChar; uCommand: UINT;
    dwData: DWORD): HWND; stdcall;
var
  HelpModule: HModule;
  HtmlHelp: TFNHtmlHelpA;
begin
  Result := False;
  HelpModule := LoadLibrary(''''HHCTRL.OCX'''');
  if HelpModule <> 0 then
  begin
    @HtmlHelp := GetProcAddress(HelpModule,
      ''''HtmlHelpA'''');
    if @HtmlHelp <> nil then
      Result := HtmlHelp(Application.Handle,
        PChar(Application.HelpFile),
        Command,
        Data) <> 0;
    FreeLibrary(HelpModule);
  end;
  CallHelp := False;
end;

Dynamically loaded BPLs

BPLs are just as simple. Well almost.

We dynamically load the package by using the LoadPackage function.

function LoadPackage(const Name: string): HMODULE;

We create TPersistentClass of the class we wish to instantiate by using the GetClass function.

function GetClass(const AClassName: string):
  TPersistentClass;

Instantiate an object of the loaded class and use it.

And when we are done, unload the package using the UnloadPackage procedure.

procedure UnloadPackage(Module: HMODULE);

Let us go back to our example and make a few changes:

  1. Select "Project1.exe" from the project manager.
  2. Right-click and select "Options..."
  3. Select the "Packages" tab.
  4. Remove "Package1" from the "Runtime packages" edit-box section and OK the options.
  5. On Delphi''''s toolbar, click on the "Remove file from project" button.
  6. Select "Unit2 | Form2" from the list and then "OK."
  7. Now go to the "Unit1.pas" source and remove Unit2 from its uses clause. (These steps are required to remove any link to Unit2 and the package we wish to load dynamically.)
  8. Go to the source of Button1''''s OnClick event.
  9. Add two variables of type HModule and TPersistentClass.
    var
      PackageModule: HModule;
      AClass: TPersistentClass;
  10. Load the package Package1 by using the LoadPackage function.
      PackageModule := LoadPackage(''''Package1.bpl'''');
  11. Check that the Package Module is not 0 (zero).
  12. Create a persistent class using the GetClass function, passing it the name of the form within the package as its parameter:
      AClass := GetClass(''''TForm2'''');
  13. If the persistent class is not nil, create and use an instance of the class just a before.
      with TComponentClass(AClass).Create(Application)
        as TCustomForm do
      begin
        ShowModal;
        Free;
      end;
  14. Finally, unload the package using the UnloadPackage procedure:
      UnloadPackage(PackageModule);
  15. Save the project.

Here is the complete listing of the OnClick event:

procedure TForm1.Button1Click(Sender: TObject);
var
  PackageModule: HModule;
  AClass: TPersistentClass;
be

[1] [2]  下一页


[办公软件]PowerPoint模板使用经验之谈  [办公软件]教你在Powerpoint中设置页眉页脚
[办公软件]在Powerpoint中如何插入Flash动画  [办公软件]如何在Powerpoint 中(实现)输入上标、下标
[办公软件]如何在PowerPoint同一张幻灯片中显示大量文字  [办公软件]这样来修改PowerPoint超级链接的文字颜色
[办公软件]PowerPoint小小操作技巧,让您工作更轻松  [办公软件]如何在office(PowerPoint,Word,Excel)中制作带圈的…
[办公软件]保留PowerPoint超链接,但是取消超链接的下划线  [办公软件]挖掘PowerPoint图片自动压缩功能在不失真的情况下…
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台