附录A使用OPENTOOLSAPI的D扩展示例_第1页
附录A使用OPENTOOLSAPI的D扩展示例_第2页
附录A使用OPENTOOLSAPI的D扩展示例_第3页
附录A使用OPENTOOLSAPI的D扩展示例_第4页
附录A使用OPENTOOLSAPI的D扩展示例_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、 PAGE 532Delphi 6运用开发指南.附录A 运用OPENTOOLS API的Delphi扩展例如 PAGE 531:.;附录A 运用OPENTOOLS API的Delphi扩展例如附录A与第11章的内容前后承袭。阅读第11章之后,您曾经了解了创建定制组件的大部分知识。附录A也很重要,它示范了如何创建组件编辑器以及运用OpenTools API对Delphi本身进展扩展。二者分属不同的主题:一个与组件相关,另一个那么是要扩展Delphi。之所以将二者放到附录中,是由于它们没有其他技术那样常用。但要用到二者的时候,它们都是很有用的。定制组件编辑器可以定义设计时对话框,编辑器在Objec

2、t Inspector不够用时,使得用户可以可视化地修正特定于该组件的每个方面。一个很好的例子就是TChart组件,由Dave Berneda开发。另外,在设计时您还可以从组件的上下文菜单中运转该组件所包含的代码。假定您运用Delphi曾经有一段时间了,而您以为Delphi缺乏某些必要的特征。我三年前在一个工程上任务时,就发生了这样的情况。当时正在对Rational Rose所定义的系统构造模型进展编码,我们曾经腻烦了手工定义类并编写函数体。真实是太烦了。创建一个类来读取类的声明并编写函数体,这看来是个不错的主意。运用OpenTools API,有时候再借助一下Ray Lischner的书,我

3、们最终向Delphi添加了一个可以调用类生成器的菜单项。结果终于摆脱了这本来可以自动完成的、烦人的义务惋惜的是我们没有一本语法分析方面的好书,我有点离题了。这准确地描画了Inprise公司在决议向Delphi专业版和企业版用户提供OpenTools API时的想法。当需求Delphi具有某些功能时,添加上去就行了。Delphi如今还具有“Complete class at cursor的代码生胜利能,因此我们可以创建一个尚不存在的专家:可以生成专家的专家。当您阅读本章后,可以了解到如何创建组件编辑器以及怎样运用专家对Delphi进展定制。有一个工具可用于开发定制专家,这使得创建专家与创建组件一

4、样容易。A.1 OpenTools API引见OpenTools API原来定义为笼统虚类,即它运用了Delphi接口,而我们可以承继它以便向Delphi添加扩展。原来的那些单元依然存在于他安装的Delphi的SourceToolsAPI子目录下,但在大多数情况下它们曾经让位于ToolsAPI.pas单元中定义的COM接口。留意:ToolsAPI单元与Delphi专业版和企业版一同发布。您也可以对Delphi规范版进展定制,只是包含相应接口的单元在Delphi规范版中是没有的。假设您对Delphi笼统接口比较熟习,那么比从零开场要好一些。不论怎样,您都应该学习COM接口,这正是我们在本章中要做

5、的。A.1.1 OpenTools接口大多数情况下,OpenTools接口都是位于SourceToolsAPIToolsAPI.pas单元中的COM接口。为提高后向兼容性,该目录下也定义了风格较老的Delphi接口。表A.1完好地列出了ToolsAPI中的一切单元。带有星号的单元包含了风格较老的Delphi接口,通常应该防止在较新的代码中运用。警告:很差的是,这些单元在协助 文件中并没有很好的文档。首先要参考单元中的代码;代码中的注释很有协助 ,但默许某些知识;而经过仔细查找,我们发现几乎完全没有集成化的协助 。这真是个不幸,假设要进展扩展,您必需阅读许多代码并进展实验。表A.1 Delphi

6、 ToolsAPI单元列表。经过实现ToolsAPI.pas单元中定义的COM接口,可以访问Delphi的大部分功能单元描画toolsapi.pas包含了新的COM接口,它交换了在其他单元中可以找到的风格较老的接口本章中将广泛地运用该单元的接口vcsintf.pas包含了与版本控制系统进展链接的COM接口dsgnintf.pas包含了特性编辑器、组件编辑器以及注册过程所需的接口例如,RegisterComponentEditoreditintf.pas*风格较老的Delphi笼统接口,用于访问编辑器缓存,例如单元的文本exptintf.pas*风格较老的单元,其中包括了用于定义专家的笼统虚类T

7、IExpert;新代码应运用ToolsAPI单元中的COM接口fileintf.pas*风格较老的单元,其中包括了用于访问文件系统功能的笼统虚接口istreams.pas*包含了流、内存流、文件流的接口toolintf.pas*与Delphi菜单和ToolServices相关的接口;在新代码中应运用ToolsAPI单元中的BorlandIDEServices COM对象以及IOTAMenuWizardvirtinft.pas*包含了TInterface的定义,以及Delphi对根本的COM接口IUnknown的实现留意:本章中能够会交替运用导游和专家这两个词。它们都是指Delphi中的专家。之

8、所以运用两个词,是由于Inprise也并未确定运用单个词。注册过程运用导游这个词,而COM接口也包含了导游这个词。在Delphi中进展讨论时,对这两个词进展区分是没有意义的。如今曾经无需了解进一步的细节了,我们来创建一个Delphi专家。A.1.2 创建导游对Delphi导游进展扩展的最为直接的途径就是实现IOTAWizard和IOTAMenuWizard接口。这两个接口都定义在ToolsAPI单元中,而且您可以看到,它们非常容易实现。留意:首字母缩略词前缀IOTA指的是Interface for OpenTools API我是这样以为的!,它也能够是指一幕希腊剧,意思是指非常小的数量由于只需

9、很少量的代码需求实现。实现IOTAWizard和IOTAMenuWizard最容易实现的导游是非常根本的IOTAWizard接口,它运用IOTAMenuWizard类来实现。IOTAWizard接口需求实现四个方法,而IOTAMenuWizard那么把一个菜单项放置到Help菜单上。由于刚刚起步,我们将以导游的方式实现一个Hello World例子。为使读者不至于绝望,将在下一节实现一个较为有用的导游。下面的代码定义IOTAWizard和IOTAMenuWizard。实现根本的导游并显示在Help菜单上,需求实现IOTAWizard接口的四个方法:GetIDString、GetName、Get

10、State和Execute。由于IOTAWizard承继了IOTANotifier接口,您还需求实现IOTANotifier接口。可以运用TNotifierObject存根类作为IOTANotifier接口的实现。IOTANotifier接口引入了AfterSave、BeforeSave、Destroyed和Modified方法,以便对事件进展呼应。对这个练习而言,该存根类就足够了。IOTAMenuWizard承继了IOTAWizard接口。在IOTAMenuWizard类中,独一需求实现的方法是GetMenuText,该方法前往在Help菜单上显示的文本。IOTAWizard = inter

11、face(IOTANotifier)B75C0CE0-EEA6-11D1-9504-00608CCBF153 Expert UI strings function GetIDString: string;function GetName: string;function GetState: TWizardState; Launch the AddIn procedure Execute;end;IOTAMenuWizard = interface(IOTAWizard)B75C0CE2-EEA6-11D1-9504-00608CCBF153function GetMenuText: strin

12、g;end;这个没有实践功能的导游定义为TDummyWizard类,该类是TNotifierObject、IOTAWizard以及IOTAMenuWizard的子类。它实现了上面代码所列出的接口中的五个方法。完好的实现代码如下。unit UDummyWizard;/ UDummyWizard.pas - Demonstrates basic wizard interface/ Copyright (c) 2000. All Rights Reserved./ By Software Conceptions, Inc. softconcepts/ Written by Paul Kimmel.

13、Okemos, MI USAinterfaceusesWindows, ToolsAPI;typeTDummyWizard = class(TNotifierObject, IOTAWizard,IOTAMenuWizard)publicfunction GetIDString : String;function GetName : String;function GetState : TWizardState;procedure Execute;function GetMenuText : String;end;procedure Register;implementationusesDia

14、logs;procedure Register;beginRegisterPackageWizard(TDummyWizard.Create);end; TDummyWizard procedure TDummyWizard.Execute;beginMessageDlg( Building Delphi 6 Applications, mtInformation,mbOk, 0 );end;function TDummyWizard.GetIDString: String;beginresult := SoftConcepts.DummyWizard;end;function TDummyW

15、izard.GetMenuText: String;beginresult := Dummy Wizard;end;function TDummyWizard.GetName: String;beginresult := Dummy Wizard;end;function TDummyWizard.GetState: TWizardState;beginresult := wsEnabled;end;end.Register过程以TDummyWizard的一个实例为参数调用了RegisterPackageWizard。您可以像安装组件一样把专家安装到包中,如上例。实践上,进展安装最容易的方法就

16、是运用Delphi中的Component | Install Component菜单项。当用户单击添加的菜单项时,即可调用这个非常根本的导游。当单击菜单项时,将调用导游实现的Execute方法来呼应。TDummyWizard在一个TMessageDlg对话框中显示本书的标题。当然,假设您确定的话,可以在Execute方法中参与几乎任何级别的复杂行为。GetIDString方法前往导游的字符串标识符。按照惯例,该ID的前缀是您公司的名字,这里运用了Software Concepts, Inc公司的注册商标SoftConcepts,并将其经过圆点衔接到导游的名字。GetMenuText的实现代码中

17、包含了显示在协助 菜单上的菜单项文本。当每次单击Delphi的Help菜单上相应菜单项时,都会调用该方法。GetName方法前往导游的名字,而GetState方法那么前往TWizardState类型值。该类型定义如下:TWizardState = set of wsEnabled, wsChecked;wsEnable表示该导游能否是活动的,而wsChecked值那么在菜单项上放置一个检查标志。从代码可以看到,根本的Help菜单导游所需的代码非常少。当安装导游后,Delphi的协助 菜单上出现了一个新的菜单项Dummy Wizard。当用户单击导游时,将调用Execute方法,从而在TMess

18、ageDlg对话框上显示文本“Building Delphi 6 Applications。关于相应的菜单项和单击后的反响,可以参见图A.1和A.2。图A.1 Dummy Wizard添加到Delphi的Help菜单图A.2 当单击Dummy Wizard菜单项时,将显示TMessageDlg对话框,其代码可以参见Execute方法注册导游把导游添加到包,并像组件一样对其进展安装,即可扩展Delphi。当把包编译为BPL库之后,将调用上一节的Register过程来进展安装。如上一小节的代码所示,RegisterPackageWizard需求导游的一个实例作为参数。RegisterPackage

19、Wizard定义在ToolsAPI.pas单元中,其参数为IOTAWizard类型的常量援用,该过程声明如下:procedure RegisterPackageWizard(const Wizard: IOTAWizard);要安装导游,可以按照以下步骤进展。在Delphi中,单击Component | Install Component菜单项。在Install Component对话框中,假设单元尚未显示在Unit file name域中,那么单击Browse按钮找到相应的单元。假设要在当前包中安装专家,单击OK。否那么单击Into new package属性页见图A.3,并给出包的名字及描

20、画。图A.3 图中为Install Component导游,用于将向 导安装到包。所需步骤与安装组件时一样当单击OK后,给出的包将在包编辑器中翻开见图A.4。单击Compile按钮见图A.4。对包进展编译之后,Install曾经可用,单击该按钮。要记住,包在本质上是动态链接库,也是一种运用程序。因此,可以而且应该像其他程序一样对选项进展设置。要参与途径和版本音讯,并记得设置对所处的开发阶段可用的编译器选项。可以参考前面的第18章,在测试时运用运转时错误和调试选项,而在测试终了后、运用程序打包之前去掉这些选项。图A.4 包编辑器用于编译并安装包A.2 创建定制导游像New Component W

21、izard这样有用的导游,可以减少编写代码的数量,使得不用手工编写一些可以自动完成的代码;而且有助于开发者在越过妨碍之后发现Delphi的一些新的功能。为坚持导游的这种功能,本节给出了一个New Expert专家;正好像New Component对话框跳过了开场组件单元的步骤一样,New Expert的作用也是类似的。A.2.1 定义New Expert WizardNew Expert的功能是,它可以生成一些与本章开头的Dummy Wizard类似的专家。而New Expert本身将安装在Component菜单上New Component菜单项之后。要建立该导游并将其安装到Component

22、菜单上,我们需求实现IOTACreator和IOTAModuleCreate,而且还需求查询BorlandIDEServices以获得INTAServices40。INTAServices40对象定义了向特定的Delphi菜单添加菜单项的行为。导游的类是TNewExpertWizard。当单击Component | New Expert菜单项见图A.5时,它生成一个与TDummyWizard几乎一样的类。将特定的行为添加到生成的Execute方法,然后就可以了。完好的代码列表如下,对相关部分的描画分为小节,以便使您可以清楚地了解其作用。图A.5 将New Expert导游添加到INTAServ

23、ices40对象之后unit UNewExpertWizard;/ UNewExpertWizard.pas - An example of a wizard that generatesthe code for a wizard/ Copyright (c) 2000. All Rights Reserved./ By Software Conceptions, Inc. softconcepts/ Written by Paul Kimmel. Okemos, MI USAinterfaceusesWindows, Controls, ToolsAPI, Forms, Menus, Cla

24、sses, SysUtils;typeTNewExpertWizard = class(TNotifierObject, IOTAWizard,IOTACreator,IOTAModuleCreator)privateFNewClassName : string;FMenuText : string;FExpertIDString : string;FExpertName : string;FUnitName : String;FWizardState : TWizardState;FMenuItem : TMenuItem;procedure AddMenuItem;procedure On

25、Click( Sender : TObject );procedure GenerateCode;publicconstructor Create; virtual;destructor Destroy; override; IOTAWizard function GetIDString : String;function GetName : String;function GetState : TWizardState;procedure Execute; IOTACreator function GetCreatorType : string;function GetExisting :

26、Boolean;function GetFileSystem : string;function GetOwner : IOTAModule;function GetUnnamed : Boolean; IOTAModuleCreator function GetAncestorName : string;function GetImplFileName : string;function GetIntfFileName : string;function GetFormName : string;function GetMainForm : Boolean;function GetShowF

27、orm : Boolean;function GetShowSource : Boolean;function NewFormFile( const FormIdent, AncestorIdent : string) : IOTAFile;function NewImplSource( const ModuleIdent, FormIdent,AncestorIdent : string ) : IOTAFile;function NewIntfSource( const ModuleIDent, FormIdent,AncestorIdent : string ) : IOTAFile;p

28、rocedure FormCreated( const FormEditor : IOTAFormEditor );end;procedure Register;implementationuses UFormMain, Dialogs, UExpertUnit;$R *.RESprocedure Register;beginRegisterPackageWizard(TNewExpertWizard.Create);end; TNewExpertWizard constructor TNewExpertWizard.Create;begininherited;AddMenuItem;end;

29、destructor TNewExpertWizard.Destroy;beginif( Assigned(FMenuItem) thenFMenuItem.Free;inherited;end;procedure TNewExpertWizard.OnClick( Sender : TObject );beginExecute;end;procedure TNewExpertWizard.AddMenuItem;varNTAServices40 : INTAServices40;ComponentMenuItem : TMenuItem;beginNTAServices40 := Borla

30、ndIDEServices As INTAServices40;if( Not Assigned(NTAServices40) then exit;ComponentMenuItem :=NTAServices40.MainMenu.Items.Find(&Component);if( Not Assigned( ComponentMenuItem) then Exit;FMenuItem := TMenuItem.Create( ComponentMenuItem );tryFMenuItem.Caption := New &Expert.;FMenuItem.OnClick := OnCl

31、ick;ComponentMenuItem.Insert( 1, FMenuItem );exceptFreeAndNil(FMenuItem);end;end;procedure TNewExpertWizard.Execute;varForm : TFormMain;beginForm := TFormMain.Create(Application);tryif( Form.ShowModal = mrOK ) thenbeginFNewClassName := Form.NewClassName;FMenuText := Form.MenuText;FExpertIDString :=

32、Form.ExpertIDString;FExpertName := Form.ExpertName;FUnitName := Form.UnitName;FWizardState := Form.WizardState;GenerateCode;end;finallyForm.Free;end;end;function TNewExpertWizard.GetIDString: String;beginresult := SoftConcepts.NewExpertWizard;end;function TNewExpertWizard.GetName: String;beginresult

33、 := Expert;end;function TNewExpertWizard.GetState: TWizardState;beginresult := wsEnabled;end;function TNewExpertWizard.NewImplSource(const ModuleIdent,FormIdent,AncestorIdent: string): IOTAFile;beginresult := TExpertUnit.Create( FNewClassName, FMenuText,FExpertIDString,FExpertName, FUnitName, FWizar

34、dState );end;procedure TNewExpertWizard.GenerateCode;begin(BorlandIDEServices as IOTAModuleServices).CreateModule(Self);end;procedure TNewExpertWizard.FormCreated(const FormEditor:IOTAFormEditor);begin/ Intentionally left blankend;function TNewExpertWizard.GetAncestorName: string;beginresult := ;end

35、;function TNewExpertWizard.GetFormName: string;beginresult := ;end;function TNewExpertWizard.GetImplFileName: string;beginresult := FUnitName;end;function TNewExpertWizard.GetIntfFileName: string;beginresult := ;end;function TNewExpertWizard.GetMainForm: Boolean;beginresult := False;end;function TNe

36、wExpertWizard.GetShowForm: Boolean;beginresult := False;end;function TNewExpertWizard.GetShowSource: Boolean;beginresult := True;end;function TNewExpertWizard.NewFormFile(const FormIdent,AncestorIdent: string): IOTAFile;beginresult := Nil;end;function TNewExpertWizard.NewIntfSource(const ModuleIDent

37、,FormIdent,AncestorIdent: string): IOTAFile;beginresult := Nil;end;function TNewExpertWizard.GetCreatorType: string;beginresult := sUnit;end;function TNewExpertWizard.GetExisting: Boolean;beginresult := False;end;function TNewExpertWizard.GetFileSystem: string;beginresult := ;end;function TNewExpert

38、Wizard.GetOwner: IOTAModule;beginresult := nil;end;function TNewExpertWizard.GetUnnamed: Boolean;beginresult := False;end;end.New Expert的类定义TNewExpertWizard类承继了TNotifierObject存根类,以及IOTAWizard、IOTACreator和IOTAModuleCreator接口。IOTAWizard是根本的导游接口,而TNotifierObject那么对该接口中某些根本的事件处置程序实现了一个存根。要创建一个根本的导游,您得实现

39、IOTAWizard接口。IOTACreator和IOTAModuleCreator用于与Delphi的文件视图协同任务,它们也包含了创建窗体和单元的才干。过一会儿我们继续讨论各个接口的实现。导游类的私有部分包含了几个字段,用于正确地创建单元。FNewClassName存储将要生成的导游的类名。而FMenuText那么存储要生成的导游的菜单文本。FExpertIDString包含了专家的ID字符串。FExpertName字段包含了专家名。FUnitName是生成的.PAS单元的名字,而FWizardState包含了wsEnabled和wsChecked值。上述的每个特性都用于生成对接口的IOT

40、AWizard部分的根本呼应。例如,IOTAMenuWizard需求用所显示的菜单文本来呼应。代码生成器将从IOTAMenuWizard.GetMenuText得到FMenuText的值。私有部分还有FMenuItem,该字段用于维护对导游所添加菜单的援用。菜单项是经过构造函数中调用的AddMenuItem过程添加到Delphi的。OnClick事件处置程序包含了当用户单击New Expert菜单项时见图A.6的呼应代码。当用户填写好如图A.6所示的New Expert对话框之后,将调用私有方法GenerateCode。对话框中讯问了一些用于完成专家的必要的问题。专家类的名字是什么?用于触发E

41、xecute方法的菜单项的文本是什么?创建的ID字符串是什么?专家的名字是什么?专家所对应的单元名是什么?Wizard State中的复选框用于生成GetState的实现代码。类的公有部分包括一些方法的声明,这些方法是必需实现的,以履行接口承继所构成的契约。另外,除了从接口承继的方法之外,还包括构造函数和析构函数。构造函数将New Expert菜单项添加到Delphi,而析构函数担任释放相应的内存。图A.6 用于生成Delphi专家的New Expert对话框实现IOTAWizard IOTAWizard接口需求实现GetIDString、GetName、GetState以及Execute方法

42、。GetIDString方法前往SoftConcepts.NewExpertWizard。按照惯例,ID字符串包括公司名和导游名,用圆点衔接。GetName前往Expert,这是该导游所显示的名字。GetState前往包含wsEnabled的TWizardState集合,确保Component菜单上的导游是可用的。IOTAWizard接口中独一较为困难的方法是Execute。当单击New Expert菜单项时见图A.5,将调用Execute方法。Execute方法显示一个对话框,如图A.6所示。填写New Expert对话框的一切域,然后单击OK。由New Expert对话框得到的数据存储在相

43、关的私有字段中,然后调用GenerateCode方法。GenerateCode调用IOTAModuleServices.CreateModule方法。由于TNewExpertWizard承继了IOTACreator,因此它可用作CreateModule的参数。接着,CreateModule调用IOTAModuleCreator的方法,包括用于生成代码的NewImplSource方法参考“向Delphi的菜单添加菜单项一节,那里提供了关于如何从COM对象BorlandIDEServices查询ToolsAPI效力的简要讨论。实现IOTACreator IOTACreator定义了用于与Delph

44、i的文件系统视图协同任务的接口。IOTACreator用于为生成代码提供方便。对于IOTACreator,我们实现了GetCreatorType、GetExisting、GetFileSystem、GetOwner以及GetUnnamed方法。从本节开头列出的代码可用看出,这些方法相对较为直观。GetCreatorType前往ToolsAPI.pas中定义的sUnit。常量sUnit包含了值Unit,表示将创建单元。GetExisting前往False,由于我们正在创建新的单元;假设援用已有的单元,那么该方法将前往True。GetFileSystem前往TFileSystem对象的ID字符串,

45、导游将运用该对象来读写文件。它并不是必需的,因此该方法前往了空字符串。GetOwner前往对拥有模块的援用。例如要将该模块添加到一个已有的工程,我们需求查询BorlandIDEServices以获得已有的工程或包。我们将运用包编辑器来将新的专家添加到某个特定的包。GetOwner方法可以前往Nil。最后是GetUnnamed方法,假设我们前往未命名的单元,该方法将前往True。假设GetUnnamed前往True,Delphi将在第一次保管单元时提示用户输入文件名。如图A.6的New Expert对话框所示,我们曾经提供了单元名。要自动生成模块并添加到翻开的包,您可以修正GetOwner方法,

46、查找活开工程组并将其作为GetOwner的结果前往。下面的代码就足够了。function TNewExpertWizard.GetOwner: IOTAModule;varModuleServices : IOTAModuleServices;ProjectGroup : IOTAProjectGroup;I : Integer;beginresult := Nil;ModuleServices := BorlandIDEServices As IOTAModuleServices;for I := 0 to ModuleServices.ModuleCount - 1 dobeginwith

47、 ModuleServices.ModulesI doif( Pos( .bpg, FileName ) 0 ) thenif( QueryInterface( IOTAProjectGroup, ProjectGroup ) =S_OK )thenbeginresult := ProjectGroup.GetActiveProject;exit;end;end;end;ModuleServices对象是由BorlandIDEServices对象前往的。将查找一切的模块,以找到包含.bpg包扩展名的模块。当找到一个包以后,QueryInterface会测试该模块能否实现了IOTAProject

48、Group接口。假设曾经实现了该接口,那么将把ActiveProject作为函数结果前往。实现IOTAModuleCreator 在这个练习中,IOTAModuleCreator包含的方法数目是最多的。为与IOTA前缀的来源相一致,这些方法也都相对直观而易于实现。表A.2包含了用于实现IOTAMoudleCreator接口的方法。虽然该表较小,但也够用了,由于描画都相对较短。表A.2 为IOTAModuleCreator接口所实现的方法。对New Expert导游最重要的是NewImplSource方法,该方法前往生成的源代码接口方法描画GetAncestorName前往模块所承继的祖先名;我

49、们运用了空字符串GetFormName该函数前往窗体名;由于并不生成窗体,所以我们也前往空字符串GetImplFileName前往由New Expert对话框读取的、存储在FUnitName中的单元名续表接口方法描画GetIntfFileNameCPP头文件名,这里前往空字符串,要记得Delphi与C+ Builder共享VCL代码GetMainForm由于本模块并非主窗体,所以GetMainForm前往FalseGetShowForm由于该导游并不与窗体相关联,所以依然前往FalseGetShowSource由于我们需求完成生成的专家导游中的Execute行为,因此前往True以显示新的单元

50、NewFormFile前往IOTAFile对象,表示窗体文件的实例;假设生成的专家不需求窗体,那么前往NilNewImplSource这是个关键性的方法:该方法前往IOTAFile的子类,包含了生成的专家的源代码。从代码可以看到,该方法前往了TExpertUnit类的实例在“建立代码生成器一节中,我们将继续讨论TExpertUnit单元NewIntFSource该方法前往C+头文件的源代码;它与我们的目的是不相关的FormCreatedFormCreated是有窗体创建时所调用的事件方法;由于New Expert导游没有窗体,因此该事件处置程序是空白的如今我们曾经实现了导游,并涵盖了一切用于定

51、义导游的接口,接下来我们需求讨论运用BorlandIDEServices对象添加菜单项。最后我们将实现生成代码的IOTAFile部分以及IOTARepository接口,并终了本节。存储库接口将把我们创建的导游放置到New Items对话框中,这样可以使得它与New Component功能相一致。A.2.2 向Delphi的菜单添加菜单项BorlandIDEServices全局变量定义在ToolsAPI.pas单元中。当对COM对象运用as操作符时,它与向一个对象查询能否支持某接口是等效的。例如,假设BorlandIDEServices实现了IOTAModuleServices接口,Borla

52、ndIDEServices as IOTAModuleServices将前往IOTAModuleServices的实例。可以运用BorlandIDEServices对象来访问一切与ToolsAPI相关的COM对象,名字形如somenameservices。下面的代码片断摘自定义New Expert导游一节。procedure TNewExpertWizard.AddMenuItem;varNTAServices40 : INTAServices40;ComponentMenuItem : TMenuItem;beginNTAServices40 := BorlandIDEServices As

53、 INTAServices40;if( Not Assigned(NTAServices40) then exit;ComponentMenuItem :=NTAServices40.MainMenu.Items.Find(&Component);if( Not Assigned( ComponentMenuItem) then Exit;FMenuItem := TMenuItem.Create( ComponentMenuItem );tryFMenuItem.Caption := New &Expert.;FMenuItem.OnClick := OnClick;ComponentMen

54、uItem.Insert( 1, FMenuItem );exceptFreeAndNil(FMenuItem);end;end;我们首先需求经过BorlandIDEServices获取对INTAServices40接口的访问权限。INTAServices40可以访问Delphi的主菜单。TMainMenu.Items.Find方法可用于获取Items集合中Component菜单的援用。加速键字符&会被忽略,运用与否都是可以的。两种情况下find都能正确任务。假设找到了Component菜单,将创建一个新的菜单项并将其赋值给FMenuItem字段变量。再初始化菜单项的Caption和OnCli

55、ck特性,然后插入菜单项。当以索引位置1插入菜单项时,该菜单项将出如今New Component菜单项之后。最后,假设发生异常,将释放FMenuItem对象。假定其他的开发者经常添加专家如今他们曾经创建了New Expert专家,这是能够的。为确保您的专家总是放在正确的位置上,您可以运用一点搜索逻辑来查找相对于另一菜单的正确位置。下面的修正确保了New Expert总是出如今New Component菜单项之后原来的代码是ComponentMenuItem.Insert( 1, FMenuItem);。varI : Integer; / added an integer variableNew

56、ComponentMenuItem : TMenuItem;/ original variablesbegin/ original codeNewComponentMenuItem := ComponentMenuItem.Find(New Component);I := ComponentMenuItem.IndexOf( NewComponentMenuItem );ComponentMenuItem.Insert( I + 1, FMenuItem );修正后的版本交换掉了原来对Insert的单独一行的调用。ComponentMenuItem.Insert(ComponentMenuIt

57、em.IndexOf(ComponentMenuItem.Find(Install Component.) + 1,FMenuItem );当然,假设运用原来的版本,可以添加一个注释,而且不需求额外的部分变量I和NewComponentMenuItem。A.2.3 建立代码生成器在很大程度上,每个导游都包含了一些一样的根本代码。新的导游需求一个单元,其中包括单元名、接口和实现部分、援用ToolsAPI单元的uses子句、注册过程、以及对IOTAWizard和IOTAMenuWizard接口的实现。有个方便的方法可以定义要生成的代码,即使用源代码的参数化的字符串,并将其放置在资源文件中。当经过I

58、OTAModuleCreator.CreateModule方法创建IOTAFile的后代类的实例时,该实例可读出资源字符串并对参数化的空白部分进展填充。TExpertUnit类就是这样实现的。我们首先看一下资源文件的定义。定义代码资源文件可以将源代码定义为常量,但运用资源文件更为可取。定义源代码的过程可分为四步。第一步,我们从DemosExperts目录下的例子中找一些源代码,然后创建名为codegen.txt的文本文件,其中包括参数化的源代码。经过运用参数,可以用Delphi的format函数插入实践的值。第二步:创建资源代码文件,资源编译器将运用该文件生成codegen.res,这就是要链

59、接到New Expert 导游的资源文件。第三步:运用Brcc32.exe资源编译器编译资源文件。第四步:运用$R CODEGEN.RES编译指令,以确保将codegen.res链接到程序中。A.3 CODEGEN.TXT下面列出了参数化的源代码。仔细察看,可以留意到该文本与TDummyWizard非常类似。实践上,它就是从TDummyWizard导游复制过来的,一些因导游而异的关键值运用参数进展了交换。例如,单元名交换为%0:s。因此,假设对资源字符串运用Format函数,那么运用%0:s之处将交换为Format调用中的第一个字符串参数,如此等等。unit %0:s;/ %0:s.pas -

60、 Raison d etre/ Copyright (c) 2000. All Rights Reserved./ By Your Company Name Here, Inc. yourwebsite/ Written by Your Name Here. City, State USAinterfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms,Dialogs,ToolsAPI;type%1:s = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论