js333 > 计算机互联网 > 通过实例看VCL组件开发全过程金沙js333娱乐场:,

原标题:通过实例看VCL组件开发全过程金沙js333娱乐场:,

浏览次数:134 时间:2019-11-12

(接上文)

四、组件属性编辑器和组件编辑器:

通过上面的努力我们的组件似乎已经比较完美了,可我们也忽略了一些重要的细节和一些有趣的事情,这一篇我们将研究两个很有用的组件特性:

在之前开发组件核心功能时我们曾设置了两个属性BeginTime和WakeTime,他们都是字符串型的属性,然而他们所要表示的却是时间类型,这样就很有可能使组件使用者错误的编辑属性并导致转化字符串到时间时出错(当然这里只是为了文章的讲解,我们故意把它设置为了字符串类型),虽然通过浏览原代码你知道我们也做了一些代码级别的防出错处理,使当输入错误时属性自动变成‘00:00:00’,然而这对组件使用者来讲仍然显的很不友好,所以我们需要为这两个属性定制编辑器,我们的编辑器将弹出一个窗口里面有一个TdateTimePicker用来选择时间。在delphi中有许多这样的例子,例如大家都知道的lines属性,当你单击它右放的省略号时为自动弹出一个文本编辑器来编辑lines,这大大降低了组件使用者范错误的可能性。

在定制完属性编辑器以后,我们将为组件本身加入一写有趣的元素——组件编辑器,这也是在delphi中经常出现的,例如有些组件当你双击它时,它并不会进入代码编写状态,而是弹出它自己的编辑器。虽然我们的组件似乎并不需要这种特性,但为了演示它,我们也将它考虑近来,我们给我们的组件编写了一个版权信息和一个关于对话框,当组件使用者双击它时弹出关于信息(当然,这仅仅是种演示)。上面提到的两种特性由于它们只是会在设计时起作用,所以你完全可以在新的组件包中编写并注册它们,并将这个组件包设置为Designtime Only,为了方便起见我们就直接把它们和组件的单元编写在一起。注意:以下出现的一些类和方法都需要引用单元DesignEditors(delphi7)或DsgnIntf(delphi5),与前面说的一样,它们都属于delphi的open tools api所以,如果你没有这写单元请按照前文的方法安装它们。

首先来编写属性编辑器,由于BeginTime和WakeTime是字符串类型,所以我们必须从默认的字符串属性编辑器类TstringProperty继承并覆盖它的一写方法(这里只介绍几个重要的方法,事实上所有的属性编辑器都从TpropertyEditor继承而来,然而我们不用直接继承这个基类)。其中一个重要的方法是GetAttributes,他将返回一些代表编辑器功能的值,这些值将会在代码的注释中说明(如果你的属性编辑器还需要一个下拉列表,你还需要另外一个重要的方法GetValues具体请查看delphi帮助)另外为了使属性编辑器为弹出的对话框我们需要覆盖Edit方法。为了可以以可视化的方式设计对话框,我们可以建立一个普通工程,在设计好后将窗体的类声明复制到我们的组件单元,并将窗体的dfm文件拷贝到我们的组件包目录,并在代码中加入编译器开关{$R *.dfm}。以下是窗体的类声明,这个窗体没有任何的代码需要编写:

TTimeEditFrm = class(TForm)

    DateTimePicker1: TDateTimePicker;

    Button1: TButton;

    Button2: TButton;

private

    { Private declarations }

public

    { Public declarations }

end;

以下是属性编辑器的代码:

TClockProperty=class(TStringProperty)

public

    function GetAttributes:TPropertyAttributes;override;

    procedure Edit;override;

end;

实现部分:

procedure TClockProperty.Edit;

var

TimeEditFrm:TTimeEditFrm;

begin

TimeEditFrm:=TTimeEditFrm.Create(Application);

try

  TimeEditFrm.DateTimePicker1.Time:=StrToTime(GetValue);

  if TimeEditFrm.ShowModal=mrOK then

   SetValue(TimeToStr(TimeEditFrm.DateTimePicker1.Time));

  //GetValue和SetValue是TStringProperty的基类方法,他直接读取和设置字符串的值

finally

  TimeEditFrm.Free;

end;

end;



function TClockProperty.GetAttributes: TPropertyAttributes;

begin

  result:=[paDialog,paMultiselect];

  //paDialog表示属性编辑器将显示一个对话框,paMulitiselect允许多个组件选择属性

  //除此之外如果你想让属性编辑器显示下拉列表,你还需要paValueList具体请查看帮助

end;

最后我们用RegisterPropertyEditor方法注册属性编辑器:

procedure Register;

begin

……

RegisterPropertyEditor(TypeInfo(string),TClock,BeginTime,TClockProperty);

RegisterPropertyEditor(TypeInfo(string),TClock,WakeTime,TClockProperty);

end;

重新编译更新组件后我们就可以测试了.
接下来我们来实现组件编辑器:

组件编辑器需要继承TcomponentEditor并覆盖一些重要的方法,GetVerbCount返回设计时组件右键自定义菜单的数目,GetVerb为每一个自定义菜单添加文字,ExecuteVerb为每一个菜单项添加事件,Edit为组件的缺省操作指定事件(即在设计时双击组件),以下是代码:

TClockEditor=class(TComponentEditor)

public

   function GetVerbCount:integer;override;

   function GetVerb(index:integer):string;override;

   procedure ExecuteVerb(index:integer);override;

   procedure Edit;override;

end;

实现部分:

procedure TClockEditor.Edit;

begin

  ExecuteVerb(1); //默认显示关于

end;



procedure TClockEditor.ExecuteVerb(index: integer);

begin

  case index of

   //第一个显示名字的菜单什么都不做显示

   1:showmessage([email protected]);

  end;

end;



function TClockEditor.GetVerb(index: integer): string;

begin

case index of

  0:result:=hk.barton;

  1:result:=About Clock;

end;

end;



function TClockEditor.GetVerbCount: integer;

begin

  result:=2;//我们显示两条菜单,一个我的名字,一个关于

end;

同样最后我们注册组件编辑器:

procedure Register;

begin

……

RegisterComponentEditor(TClock,TClockEditor);

end;

    


文章写到这里也该结束了,虽然写了那么多,然而在组件开发中这仍是一小部分内容,本文只是抛砖引玉的作用,希望对正要进入组件开发的朋友一些启示。为了方便你阅读本文,如果你想要本文所开发的这个组件的全部原文件,请和我联系:

E-mail:[email protected]   [email protected]      QQ:6813489

(全文完)



参考文献:

  Marco Cantu 《Mastering Delphi》

    组件包日常按运维期包和规划期包八个包来揭橥,个中运营期包中饱含了应用程序编写翻译实际必要的单元,而组件编辑器、属性编辑器那几个极度为 IDE 设计期编写的代码在应用程序的 exe 中是无需的,所以组件源码中会将这个规划编辑器的代码放到单独的 pas 文件中,那一个含有设计期 pas 的单元只在兼备期包的 dpk 中包罗,以致于那些向 IDE 中注册组件的 Register 函数也足以不放在组件单元中。

作者们事先几篇切磋过自定义数据流组件的一些技术,分别如下

Vue2.0中集成UEditor富文本编辑器的点子,vue2.0ueditor

在vue的'项目中相遇了急需运用富文本编辑器的要求,在github上看了超多vue封装的editor插件,相当多对图纸上传和录制上传的协助并不是很好,最后照旧调控利用UEditor。

那类的稿子网络有广大,作者实行了寻觅、手写代码、汇总、制版,形成了那篇随笔。

下载对应的UEditor源码

第豆蔻梢头,去官英特网下载UEditor的源码,根据你后台语言的两样下载对应的版本(PHP、Asp、.Net、Jsp卡塔尔国。

下载之后,把能源放到 /static/ue/ 静态目录下。文书档案结构如下:

金沙js333娱乐场 1

(我把UEditor放到了static静态目录上边,这里的文书不会被webpack卷入,当然你也足以采用性地放进src中卡塔 尔(英语:State of Qatar)

编写 UEditor 编辑器 配置文件

大家开荒 ueditor.config.js,改进当中的window.UEDITOR_HOME_UR配置,如下:

window.UEDITOR_HOME_URL = "/static/UE/";   //指定编辑器资源文件根目录
var URL = window.UEDITOR_HOME_URL || getUEBasePath();

ueditor.config.js文本有相当多布署,能够在那处实香港行政局地初阶化的大局配置,举个例子编辑器的暗许宽高端:

,initialFrameWidth:1000 //初始化编辑器宽度,默认1000
,initialFrameHeight:320 //初始化编辑器高度,默认320

任何的参数配置,在该公文中有详细列出,只怕仿照效法官方文书档案

将编辑器集成到系统中

张开 /src/main.js 文件,插入下边包车型地铁代码:

//ueditor
import '../static/UE/ueditor.config.js'
import '../static/UE/ueditor.all.min.js'
import '../static/UE/lang/zh-cn/zh-cn.js'
import '../static/UE/ueditor.parse.min.js'

支付公共组件 UE.vue

我们在 /src/components/ 目录下创办 UE.vue文件,作为我们的编辑器组件文件。

上边代码提供简单意义,具体应用依照要求周到该构件就可以。

<template>
  <div>
    <script type="text/plain"></script>
  </div>
</template>
<script>
  export default {
    name: 'ue',
    data () {
      return {
        editor: null
      }
    },
    props: {
      value: '',
      config: {}
    },
    mounted () {
      this.editor = window.UE.getEditor('editor', this.config);
      this.editor.addListener('ready', () => {
        this.editor.setContent(this.value)
      })
    },
    methods: {
      getUEContent () {
        return this.editor.getContent()
      }
    },
    destroyed () {
      this.editor.destroy()
    }
  }
</script>

组件暴光了七个接口:

  • value是编辑器的文字
  • config金沙js333娱乐场 ,是编辑器的安顿参数

在其余页面中央银行使该器件

简单来讲地创立三个内需UEditor的页面,再该页面中应用刚才封装好的UE.vue组件:

<template>
  <div>
    <Uediter :value="ueditor.value" :config="ueditor.config" ref="ue"></Uediter>
    <button @click="returnContent">显示编辑器内容</el-button>
    <div>{{dat.content}}</div>
  </div>
</template>
<script>
  import Uediter from '@/components/UE.vue';

  export default {
    data () {
      return {
        dat: {
          content: ''
        },
        ueditor: {
          value: '编辑器默认文字',
          config: {
            initialFrameWidth: 800,
            initialFrameHeight: 320
          }
        }
      }
    },
    methods: {
      returnContent () {
        this.dat.content = this.$refs.ue.getUEContent()
      }
    },
    components: {
      Uediter
    },
  }
</script>

效率如下:

金沙js333娱乐场 2

What's more: 服务端必要做的安顿

布署完上述内容后,调控台大概会晤世"后台配置项再次回到格式出错,上传成效将不能不荒谬使用!"的报错,
我们在编辑器中上传图片或许录制,也会产出响应的报错,那是因为尚未配备服务器的央求接口,在ueditor.config.js中,对serverUrl举办布置:

// 服务器统一请求接口路径
, serverUrl: 'http://172.16.254.49:83/File/UEditor'  //地址管你们后端要去

在vue的'项目中遭逢了亟待动用富文本编辑器的须求,在github上看了多数vue封装的editor插件...

四、组件属性编辑器和零件编辑器: 通过地点的着力大家的组件就像是早就相比完美了,可大家也不经意了部分至关心爱惜要的细节和部分...

    设计期包援引了运维期包, Delphi 的包本领是依照 unit 的,实际上build with runtime package 时,是在连接期,将对前后相继援用到的单元的连年产生对运转李包裹的外界引用。

  • 入门篇
  • 数据流组件
  • 何以在自定义数据源组件中约束客商的改观 
  • 怎么样在自定义数据源组件中为自定义属性提供UIEditor
  • 什么为自定义属性提供下拉选项
  • 哪些为自定义属性提供表明式绑定帮助

    那样的话呢,我们要编写制定一个在 IDE 中得以设置使用的机件,要求有一个TMyComp 组件的兑现,然后有几个 Register 函数将零件注册到 IDE 控件面板。借使这几个组件的质量需求编辑器,或许零件自个儿有编辑器,还亟需写一些编辑器的代码。这么些在 IDE 中用来编排组件及其本性的代码,对应用程序来讲是一直不意义的挂号组件,编辑器的 Register 函数对应用程序也是绝非意思的,何况这个编辑器是依附于 IDE 的 ToolsAPI、DesnIntf 等 OTA 单元。假诺和 TMyComp 的代码放在一个 pas 中编写翻译的时候,应用程序就还须求间

本节,将世袭探究最有叁个话题,正是说除了像如上那么提供自定义属性之外,是不是仍然是能够提供二个特意的构件编辑器。

接援引到 IDE 的那几个 OTA 单元,而实在这里样管理是不适用的。

怎么须要说那些难题啊?

    所以开采组件包的撰稿者,就引入了运营期包和统筹期包多个概念,将那个应用程序供给编写翻译到 exe 中的源代码放在组件达成的 pas 单元中,比方dclCnPack_D7.dpk的内容,里头富含的 unit,都以应用程序中用不到的,只在IDE 里头使用。

假诺大家对SSIS数据流组件比较熟谙的话,就知道各样组件都有七个编辑器。大家分别来看一下。上面小编以Excel源为例

    那一个 pas 都满含在运转期包的 dpk 文件中。运营期包在工程选项中,是设置为 Runtime only 格局。只可以用于运维期,无法实行设置。所以大家在 IDE 中开辟 CnPack_D7.dpk 文件,点 Install 是会提示错误的零器件的注册、编辑器这一个内容,很显然是要引用到构件本人的代码的。    当然,对于单个组件,可能认为分开写那四个单元太难为。但对此大型的机件包,那样分开设计就很明知道。

金沙js333娱乐场 3

    CnPack 的机件代码结构基本上就是按这么些准绳来管理的。

选择“编辑”之后

    举个例子含有 TMyComp 组件的代码在 MyComp.pas 里,而针对 TMyComp 的机件注册和编辑器,则放在 MyCompEditor.pas 里头。在 MyCompEditor.pas 中 uses MyComp 这一个单元就能够了,大器晚成份是纯运营期包,风华正茂份是在运维期包外附加的设计期代码。Register 函数也理应献身 MyCompEditor.pas 中,那么些函数应用程序的exe 是不调用的。当然,放在 MyComp 中也不会出错。

金沙js333娱乐场 4

    假设只是登记组件,由于 RegisterComponents 在 Classes 中定义,所以没什么问题,不过意气风发旦要登记属性编辑器 RegisterPropertyEditor ,则是在DesignIntf 中定义的。DesignIntf 那一个单元对应用程序来讲根本未曾用项的只是 IDE 提供的设计期接口。假使将 Register 函数放在组件实当代码中,直接引用到单元,就或许以致客商在设置编写翻译组件时现身找不到DesignIntf 的失实,因为 DesignIntf 等单元私下认可是不在 IDE 的追寻路线中的。

而选用“呈现高档编辑器”之后

    从 D6 开头,有个设计期的单元未有放出源码来(Proxies.dcu卡塔尔国,在 D6 以上版本的 DesignEditor.pas 中,达成部分引用到了那些单元,而 Borland 未有提供源码,招致大气组件运转期编写翻译然而。   Proxies 那么些单元好象是在 dsnIDEXX.bpl 里头援用了 DesignEditor 的组件,安装到 IDE 中风尚未难点,是因为安插期包是带 dsnIDE.bpl 编写翻译的,而

金沙js333娱乐场 5

应用程序编写翻译就通但是了。

 

    所以大家倡导设计期包与运作期包分开,基本上正规点的机件包都是按那个

大器晚成经看过此前的几篇小说,大家对此“高等编辑器”应该是比较纯熟的。正是说,若是大家一向在ProvideComponentProperties方法中通过上面那样的章程增多属性的话,这么些属性就能够情不自禁在高端编辑器的“组件属性”中。

形式做的。

IDTSCustomProperty90 folder = ComponentMetaData.CustomPropertyCollection.New();
folder.Name = "Folder";

 

 

那便是说,大家回去本次座谈的标题。正是说,除了那一个高级编辑器,其余三个编辑器应该怎么落到实处吗?当然,前提在于你的零器件确实相比较复杂,高等编辑器不可能满足要求。(那句话谈起来有个别刚毅,因为高端编辑器按理说应该是极高级的,呵呵)

【注意】作者倒是推荐你把所谓的高端级编辑器精晓为暗中同意编辑器。

 

根据我们事先为自定义职分项(Task卡塔尔国开拓编辑器的经历,大家简单明白下面包车型大巴有的步骤

1. 创办二个兑现了IDTSComponentUI接口的类型.该接口位于Microsoft.SqlServer.Dts.Pipeline.Design那么些命名空间

    public class MyDataSourceUIEditor : IDtsComponentUI {

        #region IDtsComponentUI 成员

        public void Delete(System.Windows.Forms.IWin32Window parentWindow)
        {

        }

        public bool Edit(System.Windows.Forms.IWin32Window parentWindow, 
            Microsoft.SqlServer.Dts.Runtime.Variables variables, 
            Microsoft.SqlServer.Dts.Runtime.Connections connections)
        {
            //这里可以创建一个窗体,供用户去进行编辑
            return true;
        }

        public void Help(System.Windows.Forms.IWin32Window parentWindow)
        {
            System.Windows.Forms.Help.ShowHelp(null, "http://www.xizhang.com");
        }



        public void Initialize(IDTSComponentMetaData90 dtsComponentMetadata, 
            IServiceProvider serviceProvider)
        {

        }

        public void New(System.Windows.Forms.IWin32Window parentWindow)
        {
        }

        #endregion
    }
  1. 下一场,在组件类地方举办点名关联

     [DtsPipelineComponent(
           ComponentType=ComponentType.SourceAdapter,
           Description="这是我的一个自定义数据源组件,它可以读取某个文件夹下面的文件信息",
           DisplayName="文件夹数据源",
           UITypeName = "MyDataFlowComponentSample.MyDataSourceUIEditor, MyDataFlowComponentSample, Version=1.0.0.0, 
    

    Culture=neutral, PublicKeyToken=5207ee26f0ac0166"

           )]
    

真的正是如上的步调。其实并不复杂,对啊。超级多本事都以想通的。

上面作者来轻巧地贯彻一下这些编辑器。为此作者索要加上三个新的窗体。

金沙js333娱乐场 6

窗体代码大约如下

using System;
using System.Windows.Forms;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime;


namespace MyDataFlowComponentSample
{
    public partial class MyDatasourceUIEditorForm : Form
    {
        public MyDatasourceUIEditorForm()
        {
            InitializeComponent();
        }


        IDTSComponentMetaData90 metaValue;
        Variables vars;
        Connections conns;

        /// <summary>
        /// 这个特殊的构造器可以让编辑器与具体的组件进行联系
        /// </summary>
        /// <param name="meta">这个代表了组件的元数据</param>
        /// <param name="variables">这是包中的变量</param>
        /// <param name="connections">这是包中的连接管理器</param>
        public MyDatasourceUIEditorForm(IDTSComponentMetaData90 meta, 
            Variables variables, Connections connections)
            : this()
        {
            metaValue = meta;
            vars = variables;
            conns = connections;
        }

        private void btOk_Click(object sender, EventArgs e)
        {
            metaValue.CustomPropertyCollection["Folder"].Value=@"E:Temp";
            //作为演示目的,这里直接用代码给某个属性赋值
        }
    }
}

盘算好这一个窗体之后,大家再回过来修正一下UIEditor那一个项目。

    public class MyDataSourceUIEditor : IDtsComponentUI {

        #region IDtsComponentUI 成员

        public void Delete(System.Windows.Forms.IWin32Window parentWindow)
        {

        }



        public bool Edit(System.Windows.Forms.IWin32Window parentWindow, 
            Microsoft.SqlServer.Dts.Runtime.Variables variables, 
            Microsoft.SqlServer.Dts.Runtime.Connections connections)
        {
            //这里可以创建一个窗体,供用户去进行编辑

            using (MyDatasourceUIEditorForm form = 
                new MyDatasourceUIEditorForm(meta, variables, connections))
            {
                return form.ShowDialog() == DialogResult.OK;
            }
        }

        public void Help(System.Windows.Forms.IWin32Window parentWindow)
        {
            System.Windows.Forms.Help.ShowHelp(null, "http://www.xizhang.com");
        }


        private IDTSComponentMetaData90 meta;
        public void Initialize(IDTSComponentMetaData90 dtsComponentMetadata, 
            IServiceProvider serviceProvider)
        {
            meta = dtsComponentMetadata;
            //这个dtsComponentMetadata可以连接到组件的元数据,这样就可以传递给编辑器窗口,进行属性的读写
        }

        public void New(System.Windows.Forms.IWin32Window parentWindow)
        {
        }

        #endregion
    }

 

双重编写翻译项目,然后布署。

接下去大家在BI Studio中来看一下作用。大家选中组件,然后右键,编辑。果然看到了我们的窗体

金沙js333娱乐场 7

点击“鲜明”开关之后,该器件的Folder属性也真正订正为了“E:Temp”

金沙js333娱乐场 8

到这边甘休,大家就为数据源组件达成了独立的编辑器。

本文由小编:陈希章 于 2009/6/21 14:57:03 发布在:
正文版权归小编全部,能够转发,但未经小编同意必得保留此段表明,且在篇章页面分明地方给出最早的小说连接,不然保留追究法律权利的职分。
更加多博客文章,以致作者对于博客引用方面包车型客车完全声明以至合营方面的政策,请参照他事他说加以考查以下站点:陈希章的博客主旨

本文由js333发布于计算机互联网,转载请注明出处:通过实例看VCL组件开发全过程金沙js333娱乐场:,

关键词:

上一篇:C语言概述

下一篇:flower,flour