|
end;
注意:将全局的Form变量删掉,重新在TAboutEdit类中声明一个新的私有变量。
覆盖Edit函数:
procedure TAboutEdit.Edit;
begin
FFrmAbout := TfrmAbout.Create(Application);
FFrmAbout.ShowModal;
FFrmAbout.Free
end;
用来创建销毁窗体对象。
覆盖GetAttributes函数:
function TAboutEdit.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog,paReadOnly];
end;
告诉IDE将以何种工作方式进行显示,关于TPropertyAttributes可以参考帮助看看,这里不再赘述。我们这里是以只读对话框的方式显示的,Object Inspector将在About属性旁边出现一个省略号按钮。当用户单击这个按钮,就调用Edit方法。
覆盖GetValue函数,是为了省略号按钮旁出现“(About)”的字样,并且只读。
function TAboutEdit.GetValue: string;
begin
Result := ''''(About)''''
end;
好了,工作基本完成,如果你还想进一步控制,还可以在研究TPropertyEditor类的代码。这里就不细说了。
也许你产生疑问了:这样能行了吗?控件怎么知道这个Package的属性方法,没关联呀。对了,要想把编辑器和控件关联起来还要2项工作:
1、 控件增加一个string 类型的”About”属性
2、 在编辑器的单元里注册属性编辑器
第一步,很简单,大家早就熟悉增加一个属性的方法了:
private
FAbout: string
Published
Property About: string read FAbout write FAbout;
第二步,也只是在属性编辑器单元增加一个注册的全局过程函数:
procedure Register
beging
//只有一句话:
RegisterPropertyEditor(TypeInfo(string),TMyDataBaseEdit,''''About'''',TAboutEdit);
end;
现在,我来解释一下RegisterPropertyEditor函数:它用来注册一个属性编辑器,将控件中的一个属性和编辑器关联起来。
l 第一个参数:TypeInfo(string),参数原型:PropertyType:PTypeInfo它是一个指针,指向要编辑的属性的运行期类型信息,我们通过TypeInfo()获取。
l 第二个参数:TMyDataBaseEdit,参数原型:Component: Calss,用于指定这个属性编辑器所作用的组件类。
l 第三个参数是一个字符串,用于指定被作用属性的名称。
l 第四个参数用于指定属性编辑器的类型。
假如第二个参数设为nil,第三个参数设为空串,会如何呢?嘿嘿,所有string类型的属性全部变成About框了,哈哈。
大家注意,我们在这里只是简单的做了一个About对话框,目的是为了能够让大家快速清晰地了解属性编辑器的设计原理,我们也可以把它做成一个复杂的有返回值的对话框,这样我们就可以真正用对话框来编辑控件的属性了。这就要看各位的实际需要了,但万便不离其宗,呵呵。
有兴趣的话大家还可以研究一下Delphi的Source\Property Editors目录下的StringsEdit单元。(关于属性编辑器更详细的各种类型、定义可以参考《Delphi5开发人员指南》第三部分“关于组件的开发”或仔细研究DesignEditors单元)
包的设计思想
在进行编辑器设计的时候我们新建了一个Package组件包。组件包,大家应该都比较了解它了,它类似于Dll,不过只是在Delphi和CBuilder环境中通用。很好的利用此包,可以使我们的程序模块清晰,能最大限度的代码重用,使程序的体积尽量减小,而且可以在这两种语言环境中互用。这里就不多说了,否则跑题太远,有兴趣的话大家可以跟我联系,共同探讨。
现在,我来说一下为什么要和控件的包分开,单独新建一个Package组件包。
首先,分块划分好管理,这不用多说了,一个运行期包,一个设计期包,使应用程序的体积变小,省得所有关于的单元全部链接到执行程序中去(Delphi5及前版本),即使你只在程序中静态地进行链接,混合运行时和设计时的代码也将使你的代码膨胀。因为你的设计时代码在运行时不会被执行,但是编译器并不知道,所以把它也一起链接进去了。
其实重要的一个原因是,Delphi6版本以来,VCl结构对Delphi5及前版本有所调整,Borland用DesignIntf替换了DsgnIntf,而且属性编辑器也被放进DesignEditors、DesignMenus、DesignWindows和其它的一些设计文件里。特别是DesignEditors使用了其它的一个名叫Proxies的IDE文件。而Proxies被编译进了DesignIDE.bpl文件中。DesignIDE.bpl已经不再是一个可以分发的文件,我们只能在开发环境中使用,不用说,这时候编译应用程序时就出现“找不到文件”的问题了。这时,我们将运行期包和设计期包分开,将设计期包加入designide.dcp文件,分别编译包文件,就能保证正确无误,编译通过!
所以我们遵守一些约定,将使我们的代码结构达到最优化,一般设置如下:
设计时包应该包括:
1、 所有的注册声明(最好放在一个单独的单元中);
2、 所有的属性编辑器;
3、 所有的组件编辑器;
4、 将需要DesignIDE支持的包。
注:组件编辑器是通过在组件上弹出快捷菜单,象Table等组件。它的制作比较类似,是从TComponentEditor下继承来的。这里不再多讲了。
运行时包应该包括:
1、 组件本身。
2、 组件可能在运行时调用的窗体(属性编辑器用到的)。
Package部分由于版本不同而对不同的版本要进行不同的设计,Delphi 6.0的编辑器版本是VER140,Delphi 5.0的编辑器版本是VER130,如果我们想适应不同的版本需要使用 {$IFDEF VER140}。。。{$ELSE}。。。{$ENDIF};在Uses域进行控制,这点大家稍加注意。
以上,是本人关于Delphi制作数据感知控件的经验之谈,希望能给各位一点启发,在开发的路上少走弯路。有认识不严密的地方,欢迎大家斧正,共同探讨!我的Email:weikang_wang@163.com
上一页 [1] [2] 没有相关教程
|