当前位置:首页 » 软件开发
开发技术指南» 文章正文
    引言: Delphi的包是Delphi IDE的核心技术,没有包也就没有了Delphi的可视化编程。
 

 

    摘要: 新开一个project,然后拖两个button放在窗体上代码如下:unit unit1; interface uses windows, messages, sysutils, variants, classes, graphics, controls, forms, dialogs, stdctrls; type tform1 = class(tform) btnaddbutton: t......
    摘要: uses commctrl; var oldwindowproc: twndmethod; procedure tform1.mywindowproc(var msg: tmessage);begin if msg.msg = cn_notify then begin case twmnotify(msg).nmhdr.code of mcn_getdaystate: memo1.lines......


动态加载和动态注册类技术的深入探索
delphi的包是delphi ide的核心技术,没有包也就没有了delphi的可视化编程.包也可以用在我们开发的项目中,其好处是可以代码共享,减小工程尺寸,单纯通过替换包文件就能实现工程的升级与补丁.但是我们要加载包,就要知道包中已经存在的类.关于如何动态加载包的资料比比皆是我就不想就此问题讨论了.但是delphi的ide很是特殊,它无需事先知道你的包有哪些类就能注册组建,创建组建.但是borland没有公开bpl文件的格式.我们自己是否可以实现ide的功能呢?

首先我们知道.一个组件包想要能在ide中使用就要进行注册也就是要创建一个过程例如: 【程序编程相关:自己编写树(Tree)的封装类

【推荐阅读:为Windows Service添加服务

procedure register; 【扩展信息:报名机器人

begin

   registercomponents(ide中的页面, [组件类]);

end;

在ide加载时就要调用这个过程进行注册.

其次我们通过borland的文档又知道bpl只是一种特殊格式的dll文件.那么既然ide可以调用得到注册过程那么注册过程一定要是导出类型(exports)的才行.既然如此我们可以想办法弄明白.写一个包文件.里面包含test.与testbtn两个单元.两个单元分别都有注册过程,然后编译成bpl文件.好了我们可以用exescope这个工具来弄清楚其中的奥秘.

我们可以看到一个函数@test@register$qqrv.几乎可以肯定这个函数就是bpl把test单元中的register导出的注册函数,而那个@testbtn@register$qqrv就一定是testbtn这个单元的注册函数.可以做一个实验来证明我们的想法,在test单元的register的函数中加上showmessage(‘你好,你调用了注册函数’);

然后在我们来调用一下包中的函数@test@register$qqrv,随便写一个工程看看是不是可以调用得到test单元中的register过程.

var

  h                 : integer;

  regproc           : procedure();

begin

  h := 0;

  h := loadpackage(testpackage.bpl);

  try

    if h <> 0 then

    begin

      regproc := getprocaddress(h,@test@register$qqrv);//载入包中的函数

      if assigned(regproc) then

      begin

        regproc();//调用函数

      end;

    end;

  finally

    if h <> 0 then

    begin

      unloadpackage(h);

      h := 0;

    end;

  end;

end;

调用的结果,果然调用到了包中terst单元的register过程.但是如何得到注册了哪些类呢?注册组件要用registercomponents函数.好在vcl体系的源代码是开放的,我们看看registercomponents是如何实现的吧.

在classes单元我们可以看到:

procedure registercomponents(const page: string;

  const componentclasses: array of tcomponentclass);

begin

  if assigned(registercomponentsproc) then

    registercomponentsproc(page, componentclasses)

  else

    raise ecomponenterror.createres(@sregistererror);

end;

画线的是一个函数指针,delphi的ide就是在这个指针所指的函数里去作具体的工作.我们也可以利用它来实现我们的注册.

procedure myregcomponentsproc(const page: string;

  const componentclasses: array of tcomponentclass);

var

  i                 : integer;

  ideinfo           : pideinfo;

begin

  for i := 0 to high(componentclasses) do

  begin


...   下一页
 ·delphi 9 一点体验    »显示摘要«
    摘要: 1.支持c#、delphi for .net、delphi for win32 2.code snippets 3.for loop(支持delphi for win32) 4.refactoring for delphi and c#(***) 5.error inside 6.help inside提示信息中的链接(***) 7.history view(****) 对于f......
» 本期热门文章:

©2000-2007 All Rights Reserved. 最佳浏览:1024X768 MSIE