• VCL (三) 属性编辑器(转)


    Delphi的属性是一个很有特色的功能,这一特性在C#里得到了很好的继承。
    对于一个类来说,属性是对类中的数据进行有效修改和访问的特殊接口。在VCL中,被published
    的属性还有一个特性,就是可以在界面设计过程中对属性进行设置.
    属性的类型
    数字、字符、布尔、枚举、TStrings、集合,类对象或者接口类型等
    示例:
    TEnumTest=(etNone,etTestInt,etTestString);
    TTestcontrol=class(TCustomControl)
    private
       FInt : integer;
       FEnumTest :TEnumTest;
       FCaption :string;

    function GetInt :Integer;
    funtion GetEnumTest:TEnumTest;
    function Caption:String;

    procedure SetCatpion(AValue:String);
    procedure SetInt(AValue:Integer);
    procedure SetEnumTest(AValue:String);
    published
       property IntProp :Integer read GetInt write SetInt;
       property EnumTest:TEnumTest read GetEnumTest write SetEnumTest;
       property Caption:String read FCaption write SetCaption;
    end;
      
    read 和 write 指令指定了访问属性的有效方法,在这些方法里可以实现对属性的访问封装。

    写VCL控件最重要的就是属性编写,属性编辑器又是其中的难点。
    属性编辑器一般有数字、字符串、集合、类、Color、Font类型编辑器,Delphi内建基本编辑器声明有
    TPropertyEditor 所有的属性编辑器都必须继承于此或他的派生类
    TOrdinalProperty 这是几个有序属性编辑器的基类,如TIntegerProperty TCharProperty TEnumProperty
    TIntegerProperty 适用编辑整型属性
    TCharProperty 适用编辑字符型属性
    TEnumProperty 适用编辑枚举型属性
    TBoolProperty 适用编辑布尔型属性
    TFloatProperty 适用编辑浮点型属性
    TStringProperty 适用编辑字符串型属性
    TClassProperty 适用编辑对象类型
    TComponentProperty 使用编辑引用一个组件属性
    TSetProperty 适用编辑集合类型
    上述可以查看DesignEditors.pas单元(Delphi7)
    对于一些基本数据类型有时并不需要创建属性编辑器,因为数据类型本身也会数据进行检查,
    在当你有特殊的检查时,你可以从上述基本编辑器派生出自己的属性编辑器

    对话框型属性编辑器的编写
    定义一个正对字符型属性编辑的对话框界面,在界面上放一个memo, 一个Label, 三个按钮
    代码如下
    unit uStringEditor;

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, StdCtrls, Buttons,DesignIntf,DesignEditors;

    type
    //对话框属窗体类
    TMyStringEditDlg = class(TForm)
        Memo: TMemo;
        OkButton: TBitBtn;
        CancelButton: TBitBtn;
        Label1: TLabel;
        BitBtn1: TBitBtn;
        procedure MemoKeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
        procedure FormDestroy(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure UpdateStatus(Sender: TObject);
        procedure BitBtn1Click(Sender: TObject);
    private
        { Private declarations }
        FModified: Boolean;

    protected
        function GetLines: TStrings;
        procedure SetLines(const Value: TStrings);
        function GetLinesControl: TWinControl;
    public
        { Public declarations }
        property Lines: TStrings read GetLines write SetLines;
    end;
       
       //对话框属性编辑器
        TMyStringProperty = class(TStringProperty)
        protected
          function EditDialog: TMyStringEditDlg; virtual;
        public
          procedure Edit; override;
          function GetAttributes: TPropertyAttributes; override;
        end;

    var
    MyStringEditDlg: TMyStringEditDlg;

    implementation
    {$R *.dfm}
    const                                   //v1.73 19/08/2000)
    CopyRightStr: PChar = 'String Editor v1.0 (12/06/2003)'+#13+#13+
        'Created By Donson Wan '#13+#13+   
        'Compiled in '+
        {$IFDEF VER80} 'Delphi 1.0' {$ENDIF}
        {$IFDEF VER90} 'Delphi 2.0' {$ENDIF}
        {$IFDEF VER100} 'Delphi 3.0' {$ENDIF}
        {$IFDEF VER120} 'Delphi 4.0' {$ENDIF}
        {$IFDEF VER130} 'Delphi 5.0' {$ENDIF}
        {$IFDEF VER140} 'Delphi 6.0' {$ENDIF}
        {$IFDEF VER150} 'Delphi 7.0' {$ENDIF}
        {$IFDEF VER93} 'C++Builder 1.0' {$ENDIF}
        {$IFDEF VER110} 'C++Builder 3.0' {$ENDIF}
        {$IFDEF VER125} 'C++Builder 4.0' {$ENDIF};

    var
    StoredWidth, StoredHeight, StoredLeft, StoredTop: Integer;


    function TMyStringEditDlg.GetLines: TStrings;
    begin
    Result:=Memo.Lines;
    end;

    function TMyStringEditDlg.GetLinesControl: TWinControl;
    begin

    end;

    procedure TMyStringEditDlg.MemoKeyDown(Sender: TObject; var Key: Word;
    Shift: TShiftState);
    begin
    if Key = VK_ESCAPE then CancelButton.Click;
    end;

    procedure TMyStringEditDlg.SetLines(const Value: TStrings);
    begin
    inherited;
    Memo.Lines.Assign(Value);
    end;

    procedure TMyStringEditDlg.FormDestroy(Sender: TObject);
    begin
    StoredWidth := Width;
    StoredHeight := Height;
    StoredLeft := Left;
    StoredTop := Top;
    end;

    procedure TMyStringEditDlg.FormShow(Sender: TObject);
    begin
    if StoredWidth <> 0 then
        Width := StoredWidth;
    if StoredHeight <> 0 then
        Height := StoredHeight;
    if StoredLeft <> 0 then
        Left := StoredLeft
    else
        Left := (Screen.Width - Width) div 2;
    if StoredTop <> 0 then
        Top := StoredTop
    else
        Top := (Screen.Height - Height) div 2;
    end;

    procedure TMyStringEditDlg.UpdateStatus(Sender: TObject);
    begin
    if Sender = Memo then FModified := True;
    end;
    { TMyStringProperty }

    procedure TMyStringProperty.Edit;
    begin
    inherited;
    with EditDialog do
    try
        Lines.Text := GetValue;
        FModified:=False;
        UpdateStatus(nil);
        //ActiveControl := GetLinesControl;
        case ShowModal of
          mrOk: begin
                SetValue(Lines.Text);
                //Designer.Modified;
                end;
        end;
    finally
        Free;
    end;
    end;

    function TMyStringProperty.EditDialog: TMyStringEditDlg;
    begin
    Result := TMyStringEditDlg.Create(Application);
    end;

    function TMyStringProperty.GetAttributes: TPropertyAttributes;
    begin
    Result := inherited GetAttributes + [paDialog] - [paSubProperties];
    end;

    procedure TMyStringEditDlg.BitBtn1Click(Sender: TObject);
    begin
          MessageDlg(StrPas(CopyRightStr), mtInformation, [mbOk], 0);

    end;

    end.

    可以用上述编辑器注册给TTestcontrol.Caption 属性
    注册属性编辑器的声明为
    RegisterPropertyEditor(PropertyType:PTypeInfo;
    ComponentClass: Tclass;Const PropertyName:String;
    EditorClass: TPropertyEditorClass);

    RegisterPropertyEditor(TypeInfo(string), TTestcontrol, 'Caption', TMyStringProperty);
    如上就注册成功了,
    参数1是Typeinfo(string)是取得属性运行时刻属性类型信息,
    参数2是指定注册控件对象,如果不指定控件对象就注册给Delphi所有控件了, 这样你往界面上拉一个Label时,
    原来不能写多行文本时现在也解决了,现在你可以在弹出属性编辑器里输,可以任意行:)

    参数3是指定注册属性名
    参数4就是你需要注册的属性编辑器类名了

    另外还可以给你注册的属性加一个归类CategoryName,我们把上述Caption属性指定为MyCategory型属性,注册示例如

    下:RegisterPropertiesInCategory('MyCategory', TTestcontrol, ['Caption']);

  • 相关阅读:
    商业即生活,一些思考和感悟
    Unity中使用摇杆控制
    在家乡做什么生意比较好?且看雷家第一智囊的分析
    Android5.0之Toobar的使用
    Android5.0常用颜色属性说明
    hiho week 38 P1 : 二分·二分答案
    CCF模拟题 字符串匹配
    CCF模拟题 最优配餐
    CCF模拟题 相反数
    CCF模拟题 最优灌溉
  • 原文地址:https://www.cnblogs.com/ghd2004/p/1274243.html
Copyright © 2020-2023  润新知