打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
大富翁论坛-富翁笔记-Delphi中的属性编辑器

★★★Delphi中的属性编辑器
   在Delphi 5中给属性编辑器提供了新的特性,使我们能够以任何形式显示属性的名称和值,
比如如果属性有一个下拉列表,我们就可以为每一个列表项添加一个图标。
   所有的属性编辑器都是从TpropertyEditor 继承下来的。我们可以为特定的属性类型、属性
名或控件注册一个属性编辑器。Object Inspector检查每一个要显示的属性的名称和类型,选择
合适的属性编辑器类。然后它会创建这个类的一个实例(每个属性对应一个实例)。当我们选择
了另一个控件,Object Inspector会释放全部的属性编辑器对象,然后为新的控件创建新的对象。
   属性编辑器可以决定如何显示属性的值以及用户如何设定一个新的属性值。它通过重载
TpropertyEditor的一个或多个方法来实现的。

★★TPropertyEditor
   是所有属性编辑器的基类。

一、属性
   Designer: IFormDesigner;  提供对IDE 中的窗体设计器对象的访问;
   PrivateDirectory: string; 指定保存辅助文件的位置;在以下键值中保存:
     HKEY_CURRENT_USER\Software\Borland\Delphi\x.0\Globals\PrivateDir
   PropCount: Integer;       指明在编辑属性的组件的数量;
   Value: string;            代表由GetValue返回的字符串形式的属性的当前值;

二、方法
   Activate; virtual;        当在Object Inspector中一属性被选择时响应;(为空)

   AllEqual: Boolean; virtual; 返回是否所有被选择的组件的某属性有相同的值;
     如PropCount为1则返回True.  (仅在GetAttributes的返值包括paMultiSelect被调用)

   AutoFill: Boolean; virtual; 返回是否属性值可以键入并自动完成;(返回True)
                          (仅在GetAttributes的返值包括paValueList被调用)

   Destroy; override;        析构一个属性编辑器的实例;

   Edit; virtual;  当在Object Inspector中双击一属性(或点...按钮)时响应;

   GetAttributes: TPropertyAttributes; virtual;
     描述属性以便Object Inspector提供合适的控制(决定显示哪个控件及调用什么
属性编辑方法);其返值定义如下:
     paValueList 可以从下拉列表中选择属性值,适用于枚举型的属性TForm.BorderStyle和
整型变量如TColor、TCharSet;(此时应覆盖GetValues方法以提供枚举值)
     paSortList 按字母顺序排列属性值的列表;
     paSubProperties 包含子属性,子属性右缩进显示。适用于集合类型的属性,如TOpenDialog.Option和TForm.Font;(此时应覆盖GetProperties方法以提供子属性值)
     paDialog 在Object Inspector上将出现一个省略号按钮,单击这个按钮,将调用
属性编辑器的Edit 方法打开一个对话框,用于TForm.Font这样的属性;
     paMultiSelect 允许为多个组件选择属性值,有的属性没有这个功能,如Name属性;
     paAutoUpdate 当属性的值有变化,就调用SetValue把值写到.DFM文件中,适用用于TForm.Caption等属性;
     paReadOnly 属性是只读的;
     paRevertable 属性的值可以恢复为以前的值。TFont等嵌套的属性不应恢复;
     paOwnerDrawList  可以提供自绘制的属性值列表;(用ListDrawValue方法画每个列表项,
ListMeasureHeight和ListMeasureWidth指明尺寸)
     paFullWidthName 告诉Object Inspector这值不需要交付,名称应以Object Inspector
的全宽交付;
     (返回paMultiSelect, paRevertable);

   GetComponent(Index: Integer): TPersistent;
     从当前正编辑的所有组件中返回指定的对象;

   GetEditLimit: Integer; virtual;   返回Value 属性的字符的最大长度;(返回255)

   GetName: string; virtual;         返回属性的名字;

   GetProperties(Proc: TGetPropEditProc); virtual;
     提供属性的子属性给一个回调过程;(为空)
     type TGetPropEditProc = procedure(Prop: TPropertyEditor) of object;

   GetPropType: PTypeInfo;   返回被编辑的对象的类型信息记录;
     PTypeInfo = ^TTypeInfo;
     TTypeInfo = record
       Kind: TTypeKind;
       Name: ShortString;
     end;

   GetValue: string; virtual;  返回Object Inspector用于编辑的值串;(返回srUnknown)

   GetVisualValue: string;   返回一个用于显示的字符串;(如AllEqual为True则返回
GetValue的值,否则返回空)

   GetValues(Proc: TGetStrProc); virtual;  提供属性的枚举值给一回调过程;(为空)
     type TGetStrProc = procedure(const S: string) of object;

   Initialize; virtual;  初始化属性编辑器(创建后使用前);(为空)

   ListMeasureHeight(const Value: string; Canvas: TCanvas; var AHeight: Integer);
dynamic;  计算自绘制列表项的高度;

   ListMeasureWidth(const Value: string; Canvas: TCanvas; var AWidth: Integer);
dynamic;  计算自绘制列表项的宽度;

   ListDrawValue(const Value: string; Canvas: TCanvas; Rect: TRect; Selected: Boolean);
dynamic;  为一个属性值绘制一个列表项(在Object Inspector提供的Canvas上);

   PropDrawName(ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean);
dynamic;      属性绘制名字;

   PropDrawValue(ACanvas: TCanvas; const ARect: TRect; ASelected: Boolean);
dynamic;      属性绘制值;

   Revert;                恢复所有对象的属性为其初始值;

   SetValue(const Value: string); virtual;  当用户改变属性值时响应;(为空)

   ValueAvailable: Boolean; 指明是否所有被编辑的组件有一个值(有csCheckPropAvail
在其ComponentStyle中时);

   以上均为Public 方法,以下均为protected方法:

   GetXXXValue: TXXX;  返回当前被编辑的第一个对象的属性值;
   GetXXXValueAt(Index: Integer): TXXX;  返回指定对象的属性值;
   SetXXXValue(Value: TXXX);   改变每一个被编辑的对象的属性值;
   以上均为一类方法,其中XXX可以是Float,Int64,Method,Ord,Str,Var, TXXX为其对应的类型;

   Create(const ADesigner: IFormDesigner; APropCount: Integer); virtual;
     创建一个属性编辑器的实例;

   GetPropInfo: PPropInfo;   返回被编辑的对象的属性信息记录;

   Modified;   告诉设计器属性值已经改变;

★★★如何自定义属性编辑器

一、派生出一个属性编辑器对象:
   Delphi的DsgnIntf.pas(D5)单元中声明了几个属性编辑器,它们都是从一个共同的基类
TPropertyEditor 继承下来的。当创建一个属性编辑器时,属性编辑器必须继承于TPropertyEditor
或它的派生类。
   TOrdinalProperty  这是几个有序属性编辑器的基类,如TIntegerProperty、TEnumProperty、
TCharProperty等
   TIntegerProperty  适用于编辑整形属性
   TCharProperty     适用于编辑字符型属性
   TEnumProperty     适用于编辑枚举型属性
   TFloatProperty    适用于编辑浮点型属性
   TStringProperty   适用于编辑字符串型属性
   TSetElementProperty   适用于编辑集合中的元素,每个元素被看作单独的布尔选项
   TSetProperty      适用于编辑集合类型的属性
   TClassProperty    适用于编辑对象类型的属性
   TMethodProperty   适用与编辑方法指针类型的属性
   TComponentProperty  适用于编辑引用一个组件的属性。这种编辑器不同于TClassProperty
编辑器。相反,这种编辑器允许用户用ActiveControl 指定一个组件
   TColorProperty    适用于编辑TColor类型的属性
   TFontNameProperty 适用于编辑字体的名字,它可以让你从一个下拉列表中选择一种字体
   TFontProperty     适用于编辑TFont 类型的属性。因为它派生自TClassProperty,它允许
进行子属性编辑
   至于究竟需要选择哪个编辑器,这取决于需要编辑哪些属性。如需要编辑一个整型的属性,
就可用TIntegerProperty作为属性编辑器。如要在编辑属性的同时加入其他功能,则需要以TIntegerProperty为祖先类,派生出一个新的属性编辑器。

二、覆盖方法:
   当派生一个属性编辑器对象时,必须覆盖GetValue()和SetValue()这两个方法。GetValue()是
获得属性值以供在Object Inspector中显示,这个值以字符串的形式返回; SetValue()的作用是
根据输入到Object Inspect上的字符串来设置属性的值;
   如果需要获取属性的枚举值供编辑时选择,还需要覆盖GetValues()方法;
   如果需要用对话框来编辑属性,需要覆盖GetAttributes()方法,以便让Object Inspector知道
这个属性可以用一个对话框来编辑。GetAttributes()方法的返值用于设定属性编辑器的特性。
   如果GetAttributes()方法的返值包括paDialog,则还要覆盖Edit()方法以调对话框;

三、注册新的属性编辑器:
   可以调用RegisterPropertyEditor()来注册一个属性编辑器,这个过程是这样声明的:
procedure RegisterPropertyEditor(PropertyType: PTypeInfo; ComponentClass: TClass;
 const PropertyName: string; EditorClass: TPropertyEditorClass);
   第一个参数叫PropertyType,它是一个指针,指向要编辑的属性的运行期类型信息。
   ComponentClass参数用于指定这个属性编辑器所适用的组件类。
   PropertyName参数用于指定属性的名称。
   EditorClass参数用于指定属性编辑器的类型。

具体实例可以参考C:\Program Files\Borland\Delphi5\Source\Property Editors下的单元。

★★★一个实例:
 TComNameProperty = class(TStringProperty)
 public
   function GetAttributes: TPropertyAttributes; override;
   procedure GetValues(Proc: TGetStrProc); override;
 end;

{ TComNameProperty }

function TComNameProperty.GetAttributes: TPropertyAttributes;
begin
 Result := [paMultiSelect, paRevertable, paSortList, paValueList];
end;

procedure TComNameProperty.GetValues(Proc: TGetStrProc);
var
 List: TStringList;
 I: Integer;
begin
 List := TStringList.Create;
 try
   GetComPortNames(List);
   for I := 0 to List.Count - 1 do
     Proc(List[I]);
 finally
   List.Free;
 end;
end;


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
第一章 Delphi快速入门(二)
Delphi for iOS开发指南(15):在iOS应用程序中使用SQLite
Delphi快速入门一
comm.pasをdelphi 7で使う方法 : OracleWizard
JS的7种数据类型以及它们的底层数据结构
ES6,ES7,ES8,ES9,ES10新特性一览
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服