(本文在零点天地 http://myzeroworld.yeah.net 和 SJTU BBS Delphi 板同时发表,转载请保持文章完整性和相关连接)         如果说Delphi的IDE有什么优势的话,那么我想就是它本身就是由Delphi编写而成,因此我们能定制Delphi的IDE环境,通过Delphi的ToolsAPI的Com接口。     下面这个例子使用IOTAKeyboardBinding接口,实现对快捷键的重新绑定,相关的接口定义见ToolsAPI.pas。源码很简单,相信你一看就懂。该例子用来修改与中文环境冲突的Code Completion得快捷键,改成Ctrl+Alt+Shift+P和Ctrl+Alt+Shift+O,如果你遇上什么问题,请写信给我。 //EagleBufferList.pas,2002.5.24 { 
Pan Ying,Zero Studio 
All Right Reserved. The Demo show how to change Delphi's Key Binding,just in Delphi 
press Ctrl+Alt+Shift+P to use Code Completion.You can contact me by 
sending e-mail to me ([email protected]) Some code from Delphi's ToolsAPI Demo. Attention: 
This software is provided 'as-is', without any express or 
implied warranty. In no event will the author be held liable 
for any damages arising from the use of this software. This unit is free to use but the origin of this software 
must not be misrepresented, you must not claim that you 
wrote the original software. Feel free to use this component in your product including 
commercial applications. If You alert this component's code to make it better, 
please remember to tell me about it , let's to make it better 
together. This attention may not be removed or altered from any source 
distribution. Feedback: 
E-Mail: [email protected] 
HomePage:http://myzeroworld.yeah.net Version 1.1 
Remove some useless code. 
Version 1.0 
Initial Version. 
} unit EagleBufferList; interface procedure Register; implementation uses Windows, Classes, SysUtils,Menus, ToolsAPI, Controls ; type 
  TBufferList = class(TNotifierObject, IUnknown, IOTANotifier, 
    IOTAKeyboardBinding)     
    function GetBindingType: TBindingType; 
    function GetDisplayName: string; 
    function GetName: string; 
    procedure BindKeyboard(const BindingServices: IOTAKeyBindingServices); 
  protected     
    procedure CodeCompletion(const Context: IOTAKeyContext; KeyCode: TShortcut; 
      var BindingResult: TKeyBindingResult); 
  end; 
   
resourcestring 
  sBufferList = 'Eagle''s Buffer List';   //register this key binding 
procedure Register; 
begin 
  (BorlandIDEServices as IOTAKeyBoardServices).AddKeyboardBinding(TBufferList.Create);   
end; { TBufferList } 
//the code to bind key 
procedure TBufferList.BindKeyboard(const BindingServices: IOTAKeyBindingServices); 
begin 
  BindingServices.AddKeyBinding([ShortCut(Ord('P'), [ssShift, ssCtrl, ssAlt])], CodeCompletion, Pointer(csCodeList or csManual)); 
  BindingServices.AddKeyBinding([ShortCut(Ord('O'), [ssShift, ssCtrl, ssAlt])], CodeCompletion, Pointer(csParamList or csManual));   
end; //do code completion 
procedure TBufferList.CodeCompletion(const Context: IOTAKeyContext; 
  KeyCode: TShortcut; var BindingResult: TKeyBindingResult); 
begin   (Context.EditBuffer.TopView as IOTAEditActions).CodeCompletion(Byte(Context.Context)); 
  BindingResult := krHandled; end; function TBufferList.GetBindingType: TBindingType; 
begin 
  Result := btPartial; 
end; function TBufferList.GetDisplayName: string; 
begin 
  Result := sBufferList; 
end; function TBufferList.GetName: string; 
begin 
  Result := 'EagleKing.BufferList';  //do not localize 
end; end.     如果你对组件或者向导编写感兴趣,到CNPack( http://cnpack.yeah.net )来看看。

解决方案 »

  1.   

    有兴趣的朋友还可以参考GExperts中的fmIdeShortCuts单元,可以自己定义所有菜单的快捷键比如可建新建Application快捷键定义为(Ctrl+N),Delphi同胞们让我们一起来开发自己喜欢的专家!!!!
    对组件发有兴趣的朋友可以去(http://cnpack.yeah.net)看看
    GExperts源码可以在http://www20.brinkster.com/lszgx下载
      

  2.   

    ★★★★★任何Delphi爱好者都呆以加入★★★★★关于CnPack开发包
    一、 开发CnPack的目的。
    基于在大量的Delphi第三方组件代码充斥网络的今天,却仅有少量国产组件零星分布这样一个残酷的事实,我们决定以自己微薄的力量架构属于中国人自己的重量级免费第三方开发包。
    开发包定名为“CnPack For Delphi开发包”,简称CnPack,即中国人自己的免费第三方开发包,开发包的设计语种为简体中文,正式版发布时可能会推出英文版和繁体中文版,目前计划支持Delphi5、6(不排除将来支持BCB和Kylix的可能)。
    开发CnPack的最终目的是为了提高中国Delphi程序员的开发效率,减少无谓的重复开发,推动中国软件业的发展。
    二、 CnPack的版权及发布形式。
    CnPack开发包整体的著作权与版权属于CnPack开发组所有,开发包内包含的代码、单元、文档及相关内容的著作权与版权属于编写者与CnPack开发组共同所有。
    CnPack开发包以开放源码(Open Source)的形式发布,遵守LGPL条约,受LGPL条约的保护。
    更详细的内容参见“版权声明”部分。
    三、 CnPack开发内容。
    整个CnPack开发包由以下几个部分组成:
    (以下内容仅供参考,最终的开发内容将由开发成员、开发环境等因素决定)
    1、 工具组件包。
    2、 用户界面控件包。
    3、 符合中国人使用习惯的数据库、报表组件包。
    4、 网络通讯组件包
    5、 本地化、扩展的属性、组件编辑器。
    6、 IDE扩展专家工具包。
    7、 CnVCS版本控制系统。
    8、 本地化、功能强大的数据桌面、资源编辑器、组件编写工具等辅助开发工具。
    9、 大量可重用的窗体模板库。
    详细说明参见“开发包内容”部分。
    四、 CnPack开发网站。
    CnPack开发网站“中文VCL开发中心”为CnPack的开发及技术支持网站,开发组所有工作成果在此发布并接收自愿者报名以及为用户提供技术支持。
    最终的开发包中将包含一个IDE扩展专家工具,将用户的Delphi开发环境与CnPack开发网站紧密集成,提供类似Delphi.NET.CN的功能。
    详细说明参见“开发网站建设”部分。
    五、 CnPack的开发形式及开发时间。
    CnPack采用多人合作的方式开发,整个开发工作由CnPack开发组(以下简称开发组)完成。
    开发组由热衷于自由软件事业的自愿者自发组成。开发组根据工作内容的不同又分为开发包设计组、代码编写组、辅助开发组及网站维护组,各组承担开发包中相应工作。详细说明参见“开发人员组织方案”部分。
    开发包的开发时间定为2002年度,计划在第一季度内建构初具规模的开发网站、发布第一批测试代码,上半年内发布第一个较完整的测试包,2002年底或2003年上半年发布CnPack V1.0正式版。
    六、 CnPack设计规范。
    为了保证最大的代码重用性及开发包的质量,开发必须按一定的规范来进行。
    主要包括代码编写、标识符命名、版本定义、界面设计、帮助文件及相关文档编写等开发规范。
    详见“开发包设计规范”部分内容。
    七、 CnPack开发方法。
    开发包包含的每一个单元都要经过代码编写、设计组修订、内部测试、文档整理、外部测试、错误修正等步骤,以保证开发内容的整体一致性及开发质量。
    在多人开发中,开发方法的设计尤为重要,“开发包开发方法”部分内容详细定义了在多人协同开发环境下开发包的具体实现方法。开发包内容
    一、 开发包内容规划。
    开发包最终内容的制定由开发组与关注CnPack开发的热心朋友共同决定。
    在最初设计阶段,计划包含以下几大部分。
    二、 不可视工具组件包。
    包含若干从TComponent派生而来的不可视组件,用于封装操作系统底层功能调用、扩展应用程序功能以及提供一些有助于提高开发效率的封装代码。
    已计划的组件有:
    1、 使用INI文件支持多语种的组件(采用类似于RxLib中FormStorage的操作方式)。
    2、 使用方便的文件打包、恢复组件。
    3、 可选择使用Timer、MIDI序列产生器或线程方式获得不同精度的定时器。
    4、 根据CPU、内存、显存等参数给计算机分级的组件,以使程序在不同运行环境下使用不同品质的处理方式。
    5、 一个允许用键盘模拟鼠标操作的组件。
    6、 同时支持Win9X/NT/2000的32位屏幕鼠标取词组件。
    7、 农历、公历转换、日出日落时间计算、日蚀、月蚀推算及其它提供天文运算功能的组件。
    8、 应用程序病毒免疫组件。
    三、 用户界面控件包。
    设计标准:消耗系统资源少、界面美观、使用方便、显示速度快。
    已计划的内容有:
    1、 一套综合了FastLib、Graphic32、ExtraPack、FlatSytle等图像处理包优点的快速图像处理库,提供接近PhotoShop的图像处理效果。
    2、 改进的平滑字体显示库,更快的显示速度、支持更多的特效、字体自动匹配及提供封装的平滑字体对话框等。
    3、 一组用于制作“操作向导”窗体界面的控件,包括带动态切换效果可在继承窗体中使用的多页控件、操作向导树等。
    4、 一组基于快速图像处理库和平滑字体库的界面控件。
    5、 一组方便使用的“Dock”风格菜单、工具条控件。
    6、 一组伪可视组件,如特效Hint、窗体桌布、为普通控件增加移入时显示动态粒子效果的组件等。
    7、 一个仿Delphi代码编辑器操作方式,在Win9X下无64K限制的编辑器控件。
    8、 其它一些风格的界面控件,如仿Foxmail 4.0中提示窗口的控件、仿Office Xp风格的控件、液晶显示样式控件等。
    四、 符合中国人使用习惯的数据库、报表组件包。
    为中国人设计的数据库、报表组件。
    已计划的内容有:
    1、 扩展的数据库表格控件,支持多表头、自动缩放、多字体显示、多种内置编辑器、多种编辑器文本对齐方式等功能。
    2、 扩展的数据库感知组件。
    3、 用以取代无源码的QuickReport的报表组件包。
    五、 网络通讯组件包
    扩展的网络通讯组件。
    已计划的内容有:
    1、 串口通讯组件包,包含串口通讯、Modem控制、串口设置对话框等组件。
    2、 并口通讯组件。
    3、 网域网通讯组件包。
    4、 用以取代无源码的FastNet的WinSock组件包。
    六、 本地化、扩展的属性、组件编辑器。
    用来提高开发效率的工具,全部采用中文界面。
    已计划的内容有:
    1、 改进的字符串列表属性编辑器。
    2、 改进的图像属性编辑器。
    3、 改进的数值属性编辑器,增加计算器和进制转换等功能。
    4、 其它一些属性编辑器,可将已有属性的内容保存在属性字典中以供以后使用。
    5、 一个通用的组件编辑器,可将组件的部分属性(自定义)保存在组件字典中以供以后使用。
    6、 CnPack中复杂组件的组件编辑器。
    七、 IDE扩展专家工具包。
    用来提高开发效率及与开发网站集成的专家工具包,全部采用中文界面。
    已计划的内容有:
    1、 DLL型Wizard(Experts)管理工具。
    2、 一个以DelForEx功能为蓝本的源码格式化工具,提供可完全定制的代码处理方式、支持内嵌汇编格式化、大小写字母智能转换(在字典方式基础上)、函数过程按类名、字母顺序排序等功能,最重要的是与CnVCS版本控制系统兼容。
    3、 文本查找替换工具,在Delphi自带、GExpert等工具基础上提供多文档替换、忽略注释或相反等功能。
    4、 组件选择工具,提供按类型、名称(支持通配符)、父控件、表格等方式选择单个或多个组件的功能。
    5、 组件前后缀命名控制工具,可按标准或自定义的前后缀命名规范批量修改组件名、自动命名新组件的专家工具。
    6、 代码仓库工具,提供功能强大的代码库、Tips管理功能。
    7、 宏替换工具。
    8、 自动代码注释工具,可以产生一些简单的注释并允许用户扩充。
    9、 “每日提示”工具,根据用户设置类别或智能分析让程序员在每次启动Delphi时学到一点新知识。提示内容可自动从开发网站更新。
    10、 开发网站集成工具。程序员可利用该工具检索开发网站资源、与其它程序员在线交流、给开发网站或其它程序员留言或阅读留言、报告开发包Bug、下载新的开发包等。
    11、 单元引用分析工具,快速分析一个Project中引用到的所有单元(Delphi内部的和外部的)和第三方组件,可自动创建组件包文件,用于快速将整个工程移植到其它的计算机上。
    12、 使内嵌汇编支持MMX、3DNow!、SSE等扩展指令的工具(转换为DB指令)。
    13、 允许改变所选控件(集)的父控件或新建一个窗口控件将当前选择的控件(集)包含进去或删除控件的父控件而保留控件的工具。
    14、 其它辅助的IDE扩展设置,如修改IDE窗体字体、设置、定时存盘等。
    15、 自动生成用户记录类型列表、类安全列表(List)源码的工具。
    16、 其它一些窗体、模块、工程专家(RepositoryWizard)。
    八、 CnVCS版本控制系统。
    用于多人协同开发及项目管理的IDE集成工具。
    将Delphi的Project或ProjectGroup概念扩大到软件项目,包括源码、设计文档、帮助文件、资源、备份、安装程序等文档的集中管理。
    已计划的功能有:
    1、 “软件项目”文档管理功能。
    2、 用于多人协同开发的单元访问权限控制功能。
    3、 源码自动备份功能。
    4、 源码修改自动记录功能并将改动登记到数据库允许恢复。
    5、 系统版本号(主、子、Build)自动控制功能。
    6、 单元头注释统一控制功能。
    九、 辅助开发工具。
    本地化、功能扩展的辅助开发工具。
    已计划的内容有:
    1、 数据桌面。
    2、 资源编辑器。
    3、 组件编写工具。
    十、 可重用的窗体模板库。
    已计划的内容有:
    1、 各种风格的关于窗口模板。
    2、 各种风格的启动窗口模板。
    3、 操作向导窗口模板。
    4、 各种对话框模板。
    5、 不同框架结构的主窗体模板。
      

  3.   

    ★★★★★大家对开发专家有兴趣我这里还有一点资料给大家共享一下★★★在Delphi中,要撰寫專家最主要的著眼點在於「如何撰寫專家」及「與IDE環境互動」,在Hidden Paths of Delphi 3.0的寫法前者是由TIExpert繼承下來並且覆寫所有的方法,使我們對Delphi的整合環境有了第一次接觸,只要由TIExpert中呼叫我們寫的程式,也就會讓Delphi在設計時期呼叫我們的程式;但是若您要和Delphi的整合開發環境有親密接觸,那你得接觸TIToolServices類別才行,其中的函式可以讓你把玩Delphi整合環境,比如說你可以開啟或關閉一個專案,或是寫出許多可以實際產生程式的專家。
    當我拿到產生BizSnap程式碼的專家時,因為最近在看Hidden Paths of Delphi 3.0這本書,學Open Tools API如何用,所以也好奇的把其中的原始碼調出來瞧瞧,赫然發覺其中的程式我完全看不懂,怎麼Hidden Paths Of Delphi中的寫法完全沒看到,讓我大失所望;又調出Delphi的Demos中的Open Tools API範例,又是類似的寫法,都沒有自TIExpert繼承,也看不到TIToolsServices,反倒是implement一大堆Interface。
    對於這些奇怪的寫法,我找不到文件有說明,只好自行分析Open Tools API的原始碼,看來這次尋幽訪勝得靠自己了;)
    在經過一夜的Trace後,我想我大致上可以掌握了在Delphi 6所附的Open Tools API範例的寫法,在ToolsAPI單元中宣告的這些介面,不再像以往的TIInterface是繼承TObject來模擬Interface,而是用Complier原生支援的Interface,所有的Interface繼承至IUnknown;其實你在Delphi 5、6中還是可以照Hidden Paths of Delphi 3.0中的寫法,不過用Delphi所附的範例寫法會比較好,底下是我想到的優點:
    你的專家會比較有彈性:
    使用傳統的方法你必需要覆寫所有的專家方法,但是其實有些方法是不需要覆寫的,比如說若你的專家是要放在物件寶庫中那麼其實你不用覆寫TIExpert以下的這個方法「function GetMenuText: string; virtual; stdcall; abstract;」這個函式是用來回傳假如你寫得是一個標準專家或是附加專家那麼在選單上要出現的文字是什麼;藉由選擇性的implement你的專家Interface,可以只要改寫真正需要的方法就可以了。
    你的專家會有更多的功能:
    藉由IBorlandIDEServices這個介面,你可以存取到比用IToolServices更多的功能,在ToolsAPI這個單元當中只要是結尾為Services的Interface,那麼就可以被IBorlandIDEServices所轉型後使用,也就是說IBorlandIDEServices替代了IToolServices,Delphi的整合環境會自動產生一個物件,此物件實作了IBorlandIDEServices,而此物件會被自動指定到BorlandIDEServices這個IBorlandIDEServices介面變數,使得藉由BorlandIDEServices可以和Delphi的整合環境深度對話,下面是摘自ToolsAPI可被BorlandIDEServices轉型的Interface及簡短的說明,我第一次接觸還真的蠻驚訝的,竟然可以轉這麼多型別。
    Interface名稱 摘要說明
    IBorlandIDEServices 與整合環境互動的始祖,可轉型至結尾為Services的Interface,以真正提供服務。
    INTAServices 可以換掉整合環境的圖示
    IOTAActionServices 可以用來開啟檔案、關閉檔案、存檔案以及開啟專案。
    IOTADebuggerServices 用來得知除錯資訊,比如說設定了多少個中斷點,這些中斷點又在哪裡?
    IOTAEditorServices 用來和編輯器互動,比如說可以得知目前在編輯器中游標的位置或是在編輯器中加碼
    IOTAKeyBindingServices 得知鍵盤訊息,不是很清楚
    IOTAKeyboardServices 得知鍵盤訊息,不是很清楚
    IOTAMessageServices 通常在程式執行時程式編輯器下面會有一個視窗出現,用來顯示Complier的訊息,這個Interface就是和那個視窗互動的
    IOTAServices 用來得知目前的編輯環境是VCL還是CLX
    IOTAModuleServices 提供產生模組、獲得目前整合環境的模組資訊
    IOTAPackageServices 用來顯示Packages資訊
    IOTAToDoServices 提供對To-Do List的功能,比如說加入一些To-Do項目
    IOTAWizardServices 用來在設計時期動態的加入或移除專家,提供了以往只能用註冊的方式您可以看到這些豐富的介面,真是多啊!這每一個介面又牽扯到至少兩三個相關的介面,看來要詳細介紹完可得要完全改寫了Hidden Paths of Delphi了,我可沒那個本事,能讓你入門就不錯了;看來Code Site、Code Rush這類軟體就是大量用到了這些介面。
    有兩種介面我還不是很清楚,就是IOTAKeyBindingServices及IOTAKeyboardServices,我試圖開啟Editor Keybinding這個範例,裡面有對於這兩個介面的程式碼,可是無法正確的Install成功,若您知道解法的話請告訴我。
    底下我們以Delphi中所附的Open Tools API範例PackageDemo來說明專家的寫法及如何與整合環境互動,明白的講,就是要告訴你兩件事:
    1不要再繼承至TIExpert了啦!用繼承多個ToolsAPI單元中的介面這樣的方式會比較好。
    2不要再用ToolsServices這個類別了啦!用BorlandIDEServices會比較好。
    先來看看在PackageDemo中的WizMain單元中對於一個專家的宣告:
      TMenuIOTATest = class(TNotifierObject, IOTAWIzard, IOTAMenuWizard)
      public
        function GetMenuText: string;
        function GetIDString: string;
        function GetName: string;
        function GetState: TWizardState;
        procedure Execute;
      end;看起來是不是比TIExpert的宣告清爽了許多呢?有關TIExpert的宣告你可在ExptIntf這個單元中找到,我就不列出來了。其中TnotifierObject是基本和整合環境互動的類別,當整合環境發生事件時會通知您,不過TnotifierObject暗中把這些方法做掉了,ToolsAPI單元中的註解中有提到,通常我們都不會需要這些方法,好吧!也不再追究詳細的用法了。
    而實作IOTAWIzard這個介面是一個重要的關鍵,代表要這個類別要成為一個專家,底下是其介面宣告:
    IOTAWizard = interface(IOTANotifier)
       ['{B75C0CE0-EEA6-11D1-9504-00608CCBF153}']
      { Expert UI strings }
      function GetIDString: string;  //傳回唯一代表這個專家的字串
      function GetName: string; //傳回這個專家的名稱
      function GetState: TWizardState; //傳回這個專家的狀況,是要致能或是選取
    { Launch the AddIn }
     procedure Execute; //專家實際執行時會呼叫的程式碼
     end;眼尖的朋友一定會發現,原本在TIExpert中有的GetStyle方法已不復見,這個函式的傳回值決定了專家的種類,是為附加專家、標準專家、專案專家或是表格專家;底下是在ToolsAPI中結尾為Wizard的介面摘要說明,我們可以從其中的關係很容易推出若我們要寫哪一種類的專家就要實作哪個介面,是的,專家種類的選擇由函式傳回值改為實作某個介面了!介面名稱 父介面 專家類型
    IOTAWizard IOTANotifier 最基本的專家介面
    IOTAMenuWizard IOTAWizard 標準專家
    IOTARepositoryWizard IOTAWizard 物件寶庫中的專家介面
    IOTARepositoryWizard60 IOTARepositoryWizard 可以判斷是CLX還是VCL
    IOTAProjectWizard IOTARepositoryWizard 專案專家
    IOTAFormWizard IOTARepositoryWizard 表格專家若要寫個表格專家就實作IOAFormaWizard介面,一塊實作它的父介面IOTARepositoryWizard及IOTAWizard;若要寫個標準專家就實作IOTAMenuWizard介面,一塊實作它的父介面IOTAWizard,這樣的原則很容易掌握吧。在下表中更可清楚看出TIExpert與IOTAXXXWizard介面之間的差異及實作方法的說明:IOTAXXWizard 函式 說明
    TIExpert IOTAWizard function GetIDString: string; 傳回識別專家的唯一字串
    function GetName: string; 傳回專家的名稱
    function GetState: WizardState; 在選單項目中的狀態
    procedure Execute; 實際實行專家程式碼的地方
    IOTAMenuWizard function GetMenuText: string; 傳回出現在選單的名稱
    IOTARepositoryWizard function GetAuthor: string; 傳回作者名稱
    function GetComment: string; 傳回專家簡要說明
    function GetPage: string; 要在物件寶庫中哪一頁安裝
    function GetGlyph: Cardinal; 傳回代表專家的圖示
    IOTAProjectWizard 取代TIExpert中的GetStyle方法 只是單純的宣告為專案專家
    IOTAFormWizard 只是單純的宣告為表格專家
    IOTARepositoryWizard60 function GetDesigner: string; 
    property Designer: string read GetDesigner; 獲得目前的編輯環境是在VCL下還是CLX容我再說明一次,在用IOTAxxWizard介面來寫專家你只要改寫需要的方法就可以了,不用再覆載所有TIExpert的方法了;IOTAProjectWizard及IOTAFormWizard只是單純的標記此專家為專案專或是表格專家,取代了以往的GetStyle函式,在其中沒有任何的方法宣告,但是Delphi整合環境會用QueryInterface的方式來查出這些介面來判斷正確的專家類型,而安裝在正確的地方。還有一個值得一題的介面IOTARepositoryWizard60,此函式並沒有出現在 Delphi 6.0的TIExpert宣告中,實作此函式可以得知目前的設計環境是在VCL下還是CLX下,從種種的跡象看來,似乎TIExpert和TIToolsServices都和BDE的命運一樣,進入了維護階段。以下我列出PackagesDemo中的WizMain單元程式碼,對於容易理解而且上面有提過的介面及方法就用註解的方式來標記,其他的才特別加以說明。
      

  4.   

    unit WizMain;interfaceuses
      Windows, ToolsAPI, Forms, Dialogs, FrmMain, SysUtils, Graphics;
    //以前至少要使用兩個Open Tools API的單元ExptIntf及ToolInf,前者是專家的//宣告,後者是TIToolServices的宣告,現在看到ToolsAPI這個單元全包了。
    type
      TMenuIOTATest = class(TNotifierObject, IOTAWIzard, IOTAMenuWizard)
      public
        function GetMenuText: string;
        function GetIDString: string;
        function GetName: string;
        function GetState: TWizardState;
        procedure Execute;
      end;procedure Register;var
    //宣告介面變數,可取得Package資訊的介面
      PackageTest: IOTAPackageServices;
      PackageForm: TForm2;implementationprocedure Register;
    begin
      RegisterPackageWizard(TMenuIOTATest.create as IOTAWizard);//註冊專家
    end;
    //出始化專家,獲得IOTAPackageServices介面
    procedure InitExpert;
    begin
    //將BorlandIDEServices轉型為IOTAPackageServices以取得Package相關資料
      PackageTest := (BorlandIDEServices as IOTAPackageServices);
    end;//結束專家要做的事情
    procedure DoneExpert;
    begin
      { stubbed out }
    end;{ TMenuIOTATest }procedure TMenuIOTATest.Execute;
    var
      i: Integer;begin
      if BorlandIDEServices <> nil then
      begin
       PackageForm := TForm2.create(Nil);
       with PackageForm do
         {Package information}
    //取得在整合環境中的Package數目
         for i := 0 to PackageTest.GetPackageCount-1 do
    //根據索引來取得Package的名稱
           ListBox1.Items.Add(PackageTest.GetPackageName(i));
       PackageForm.ShowModal;
       PackageForm.Free;
      end;
    end;//傳回唯一識別專家的字串
    function TMenuIOTATest.GetIDString: string;
    begin
      Result := 'PackageInfoMenuId';
    end;//傳回了在Help選單項目上出現的文字,為「Package Demo」
    function TMenuIOTATest.GetMenuText: string;
    begin
      Result := 'Packa&ge Info';
    end;//傳回專家的名稱
    function TMenuIOTATest.GetName: string;
    begin
      Result := 'PackageInfoMenu';
    end;//傳回專家在選單項目上的狀態,此為Enabled
    function TMenuIOTATest.GetState: TWizardState;
    begin
      Result := [wsEnabled];
    end;initialization
      InitExpert;finalization
      DoneExpert;end.在以上的程式碼中您會發覺幾個重要的改變:
    1註冊專家的方式:
    procedure Register;
    begin
      RegisterPackageWizard(TMenuIOTATest.create as IOTAWizard);//註冊專家
    end;
    您必須先將您的「專家類別」轉型成為「專家介面」再用RegisterPackageWizard這個函式來進行註冊,取代了註冊TIExpert專家的RegisterLibraryExpert函式。
    2如何與整合環境互動:
    procedure InitExpert;
    begin
      PackageTest := (BorlandIDEServices as IOTAPackageServices);
    end;
    以往,一拖拉庫的函式都放在TIToolServices中,這次,放在IBorlandIDEServices介面,你要若取得相關的資訊,得轉型至相關的介面才可以使用,這樣分類看起來的確是清爽許多,詳細的BorlandIDEServices可轉型至何介面,請看本文第一張附表。
    3如何使用IOTAxxxServices類別:
    底下列出這個範例中的IOTAPackageServices宣告,
    //繼承至IUnknown
    IOTAPackageServices = interface(IUnknown)
        ['{26EB0E4D-F97B-11D1-AB27-00C04FB16FB3}']
        //取得目前整合環境中已安裝的Package數目
        function GetPackageCount: Integer;
        //根據索引值取得Package的名稱
        function GetPackageName(Index: Integer): string;
       //根據Package的索引值找出在這個Package中有幾個元件
        function GetComponentCount(PkgIndex: Integer): Integer;
        //根據Package及Component的索引值找出對應的元件名稱
        function GetComponentName(PkgIndex, CompIndex: Integer): string;
    //下面的屬性只是上面的函式再包裝而已
        property PackageCount: Integer read GetPackageCount;
        property PackageNames[Index: Integer]: string read GetPackageName;
        property ComponentCount[PkgIndex: Integer]: Integer read GetComponentCount;
        property ComponentNames[PkgIndex, CompIndex: Integer]: string read GetComponentName;
      end;行文至此,我想這個範例對你而言已經沒有什麼秘密了吧!剩下的就是一些UI的程式碼而已,大部份放在FrmMain這個單元中,不難,你應該可以輕易瞭解。
    ToolsAPI還有許多強大的介面等待我們去發掘,這篇文章只是個起點而已,下次來看看Borland所釋出的BizSnap專家是如何寫得吧!最後,我們來討論一下,你覺得Borland設計這些與整合環境互動的概念與技巧可否應用於你的專案上呢?你寫的物件別人只能經由介面來存取,完全看不到你實作程式碼,若要使用者提供一些資訊的話,就讓他實作某個介面,你的內部類別再去呼叫這些程式碼以真正提供服務。假如你因為這小段話而獲得啟發的話,可別忘了把你的成品發表出來看看哦!
      

  5.   

    简单的打开文件专家(向导,Expert)代码,可当专家模板用:
    安装方法:Component\Install components\选择此文件\OK
    然后看Help菜单下多出了个项,看到了么?:)  (Delphi5 enterprise compile test)
    unit u_FileOpenExpert;interfaceuses
      Dialogs, WIndows, ExptIntf;type
      TFileOpenExpert = class(TIExpert)
      public
        { Expert UI strings }
        function GetName: string; override;
        function GetAuthor: string; override;
        function GetComment: string; override;
        function GetPage: string; override;
        function GetGlyph: HICON; override;
        function GetStyle: TExpertStyle; override;
        function GetState: TExpertState; override;
        function GetIDString: string; override;
        function GetMenuText: string; override;    { Launch the Expert }
        procedure Execute; override;
      end;procedure Register;implementation{ TFileOpenExpert }procedure TFileOpenExpert.Execute;
    begin
      with TOpenDialog.Create(nil) do
      begin
        try
          Title:= GetName;
          Filter:= '所有文件(*.*)|*.*';
          if Execute then
          begin
            //其他工程已经打开,则先保存并关闭
            ToolServices.SaveProject;
            ToolServices.CloseProject;
            //打开工程
            ToolServices.OpenProject(FileName);
          end;
        finally
          Free;
        end;
      end;
    end;{$IFDEF WIN32}
    function TFileOpenExpert.GetAuthor: string;
    begin
      Result:= 'TZhuang';
    end;
    {$ENDIF}function TFileOpenExpert.GetComment: string;
    begin
      Result:= '';
    end;{$IFDEF WIN32}
    function TFileOpenExpert.GetGlyph: HICON;
    {$ELSE}
    function TFileOpenExpert.GetGlyph: HBitmap;
    {$ENDIF}
    begin
      Result:= 0;
    end;function TFileOpenExpert.GetIDString: string;
    begin
      Result:= 'BOCO.TFileOpenExpert';
    end;function TFileOpenExpert.GetMenuText: string;
    begin
      Result:= '&File Open Expert...';
    end;function TFileOpenExpert.GetName: string;
    begin
      Result:= 'File Open Expert';
    end;{$IFDEF WIN32}
    function TFileOpenExpert.GetPage: string;
    begin
      Result:= '';
    end;
    {$ENDIF}function TFileOpenExpert.GetState: TExpertState;
    begin
      Result:= [esEnabled];
    end;function TFileOpenExpert.GetStyle: TExpertStyle;
    begin
      Result:= esStandard;
    end;procedure Register;
    begin
      RegisterLibraryExpert(TFileOpenExpert.Create);
    end;end.
      

  6.   

    请问一个菜问题:cnPack上有一个coolctls.exe的控件,请问怎样注册?  谢谢