Delphi Open Tools Api实例研究(一)

Delphi Open Tools API概述     Delphi为我们提供了一组AIP(Open Tools API),允许我们使用这些函数,将自定义的菜单项、工具栏按钮、创建窗体专家以及更多的东西加入到IDE中,以提高自己的开发效率。    使用Tools API是一件很容易的事,只要实现一些特定的接口,并调用另一些接口提供的服务即可。编写一个Tools API代码和编写组件或是属性编辑器很类似,必须将这些代码编译为设计期包或是DLL 阅读详情

Delphi Open Tools Api实例研究(一)
先行知识:Delphi/接口/VCL组件包/COM(了解)
来自:http://dev.youkuaiyun.com/develop/article/21/21725.shtm
难度:★★☆☆☆

 

在这篇文章正式开始以前,首先向大家道歉。因为这个月的专栏文章本该很早就发布,但由于一些事情所以一直推迟到现在,并且这个月也只发布了这么一篇。另外,关于这篇文章我觉得我应该感谢csdn上的几位朋友,他们是chechy、FrameSniper、pankun,特别感谢chechy,让我认识到Delphi Open Tools Api(以下简称OTA)的有趣,并决定在其上面投入一些精力。并向我介绍了相当不错的资料。另外还要说明的是虽然题目叫xxxxx(一),但接下来的文章可能不是xxxxx(二)因为这个系列文章的每一篇都会是一个独立的内容,之所以叫xxx(一)是因为我会在以后的文章中不连续的些一写关于OTA的东西。

呵呵,说了那么多的废话,现在开始!但在开头还要再罗嗦一下,大概的介绍一下OTA  OTA是delphi的各个版本中都有提供的一套有趣的接口,运用它你可以任意的扩展delphi的IDE,使之符合自己的需要。例如你可以扩展IDE的菜单、代码编辑器、窗口设计器、属性编辑器和控件编辑器(这个已经在前面的一系列关于VCL开发的文章中说明过)等等,几乎你想得到的所有地方,甚至是code inside功能你都能够扩展!这个激动人心的特性在delphi5以后得到了更好的发展,变的更易于使用。使开发者可以用很少的、很基础的代码完成这些有趣的扩展实现强大的功能。通过OTA也使你能够领略到delphi IDE完美的设计,建立在COM技术基础上使得delphi IDE能够轻易被客户扩展而无须重新编译IDE。

在进行这次的例子前应该指出想要学习OTA的最好资料是位于delphi安装目录下的SourceàToolsAPI里的ToolsAPI.pas文件,它列出了所有OTA的接口并有比较详细的注释说明。另外关于OTA的站点,你可以去http://delphi.about.com/library/weekly/aa033099.htm和http://www.tempest-sw.com/opentools/看看,还可以去borland的新闻组borland.public.delphi.opentoolsapi参与讨论。当然,《delphi5开发者指南》中的26章也介绍了一些OTA的知识,并演示了如何自己实现一个delphi中的向导(本文就不讲述这个了),你们也可以去看看。

由于delphi OTA的版本差异性比较大,这个文章中的内容都以使用delphi7为前提。当delphi IDE处于运行中的时候有一个我们应该清楚的一个重要的实例(Instance)是BorlandIDEServices,它实现了众多OTA接口,换句话说我们可以从BorlandIDEServices得到很多接口,并且这些接口在delphi运行时已经被实现,我们只用通过接口调用接口方法就可以轻松的得到IDE的很多东西,比如菜单、窗口等等,有了这些,扩展delphi IDE便成为了现实。为了能够扩展delphi IDE我们必须要在delphi处于运行时进入,这意味着我们可以有两种方法来实现我们的delphi扩展(也可以叫插件)并向外发布,一种办法是将插件做成设计时VCL组件包(本文采取这种形式,关于VCL组件包请参看我在之前发表的文章),让客户在delphi运行时安装。另一种办法是将插件基于一个DLL并在注册表中的H K E Y _ C U R R E N T_ U S E R / S o f t w a r e / B o r l a n d /D e l p h i / 7 . 0 / E x p e r t s注册,并在DLL中以一个特殊的导出函数作为入口点,delphi IDE在重新启动以后便会加载你的插件(这个方法将在以后的文章中说明)。后者为建立简单化的插件安装程序提供了可能,前者需要用户在delphi运行中如同安装组件一样的进行安装。我们的例子将?

package Package1; 

//…省略编译器指示,注意将这个组件设计为设计时(Design Time)的 

requires

  rtl,

  vcl,

  designide; 


contains

  NTAMenu in 'NTAMenu.pas'; 

end.

可以看到我们将在NTAMenu.pas中实现我们的插件,在这个文件中我们主要用到了以下的接口:IOTAServices,被BorlandIDEServices直接实现的接口,是OTA的一个基础接口,我们用它的GetParentHandle方法来取得delphi IDE的句柄;INTAServices,在delphi运行时被实现的接口,可以用它的方法直接得到delphi IDE的MainMenu、ImageLis、ActionList、ToolBar这样我们就可以直接做很多操作了;IOTAModuleServices、IOTAModule、IOTAEditor、IOTASourceEditor、IOTAEditView,在代码中可以看到我们用这些接口来一步一步得到代码编辑器并最后得到一个可以在代码中当前的光标位置处理数据的IOTAEditPosition接口,我们就用它来向当前光标处插入一句代码,插入大量的代码段还可以使用IOTAEditWriter接口。关于在下面的代码中使用到的接口方法我们会在注释中做说明,没有使用到的接口和其它方法别忘了查看ToolsApi.pas文件。另外可以注意到下面的代码在很多地方进行检测以保证代码在运行后尽量不要出问题以及在出现异常时能够合理释放资源。别忘了,我们的目的是扩展delphi,而并不是要把delphi IDE弄的面目全非。

unit NTAMenu; 

interface 

uses 
  SysUtils, Classes,Menus,ToolsApi,Controls,ImgList,Graphics,Forms,ComCtrls,windows; 
type

  TNTATest = class

  private

    FMainMenu:TMainMenu;//用来存贮delphi IDE的主菜单

    NewMenu:TMenuItem;//我们将要插入的菜单

    FImageList:TCustomImageList;//用来存贮delphi IDE主菜单和工具栏的ImageList

    ImageIndex1:integer;//检测量,请参看后面的代码

    IDEHandle:HWND;//存贮IDE的handle

  protected

    procedure AddMenu;//加入我们的菜单

    procedure ReMoveMenu;//卸载我们的菜单

    procedure ReCodeEditer(sender:TObject);//菜单项一的事件

    procedure AboutForm(sender:TObject);//菜单项二的事件

  public

    constructor Create;

    destructor Destroy;override;

  end; 

procedure Register; 
var 
 MyNTATest:TNTATest; 

implementation 

procedure Register;

begin

  MyNTATest.AddMenu;

  //和传统组件的同名方法不同,这里没有在组件面板上安装图标

  //而是直接调用AddMenu方法添加我们的菜单

end; 

{ TNTATest } 

constructor TNTATest.Create;

begin

 IDEHandle:=(BorlandIDEServices as IOTAServices).GetParentHandle;

 //我们用IOTAServices接口的GetParentHandle方法取得了ide的handle

end; 

procedure TNTATest.AddMenu;

var

 MenuItem:array [0..2] of TMenuItem;

 i:integer;

 Icon1:TIcon;//菜单项一的图标

begin

  FMainMenu:=(BorlandIDEServices as INTAServices).MainMenu;

  //我们用 INTAServices的MainMenu属性直接得到了IDE的主菜单

  FImageList:=(BorlandIDEServices as INTAServices).ImageList;

  //我们用 INTAServices的ImageList属性直接得到了IDE的图象列表

  NewMenu:=TMenuItem.Create(FMainMenu);

  //创建我们的菜单

  NewMenu.Caption:='hk.barton';

  ImageIndex1:=-1;//没有载入图标

  //下面的代码使用for和case来添加两个菜单项有点小题大作,但

  //我们展示了一种更通用的方法使你能够添加更多的菜单项,而不必简单的复制代码。

  for i:=0 to 2 do

  begin

   MenuItem[i]:=TMenuItem.Create(NewMenu);//创建子菜单项

   case i of

     0:

     begin

      MenuItem[i].Caption:='InsertText';

      Icon1:=TIcon.Create;

      try

       Icon1.LoadFromFile('D:/MyWorks/MyComponent/OTATest/NewForm.ico');

       //我从硬盘的文件上载入了一个图标作为菜单项一的图标

      except

       On E:Exception do

       begin

        raise Exception.Create(E.Message);

        exit;

       end;

      end;

      ImageIndex1:=FImageList.AddIcon(Icon1);

      //加入那个载入的图标并返回一个ImageIndex

      MenuItem[i].ImageIndex:=ImageIndex1;

      MenuItem[i].OnClick:=ReCodeEditer;//添加事件处理程序

     end;

     1:MenuItem[i].Caption:='-';//当然还有一个分割符号,其实是3个菜单项

     2:

     begin

      MenuItem[i].Caption:='About';

      MenuItem[i].OnClick:=AboutForm;

     end;

   end;

   NewMenu.Add(MenuItem[i]);//添加菜单项

  end;

  FMainMenu.Items.Add(NewMenu);//最后添加我们的菜单到IDE主菜单

end;

 

procedure TNTATest.ReCodeEditer(sender:TObject);

var

   Module:IOTAModuleServices;

   CurentMoudle: IOTAModule;

   IntfEditor:IOTAEditor;

   Editor:IOTASourceEditor;

   EditView:IOTAEditView;

   EditWriterPos:IOTAEditPosition;

   i:integer;

begin

   Module:=BorlandIDEServices as IOTAModuleServices;

   CurentMoudle:=Module.CurrentModule;

 //使用IOTAModuleServices的CurrentModule方法得到当前打开的工程模块

   if CurentMoudle=nil then

   begin

     messagebox(IDEHandle,'当前没有打开项目文件','hkTest',MB_ICONINFORMATION);

    exit;

 end;

 //遍历已打开工程中所有的文件

 for i:=0 to CurentMoudle.ModuleFileCount-1 do

 begin

  IntfEditor:=CurentMoudle.ModuleFileEditors[i];

  //IOTAModule的ModuleFileEditors[]属性得到一个IOTAEditor

  if IntfEditor.QueryInterface(IOTASourceEditor,Editor)=S_OK then

  //查看遍历到的文件是否是代码文件并已开始在代码编辑器中编辑。

  //如果是便通过一个out参数Editor得到一个实现IOTASourceEditor的实例

   break;

 end;

 if Editor=nil then

 begin

  messagebox(IDEHandle,'当前没有代码编辑窗口','hkTest',MB_ICONINFORMATION);

  exit;

 end;

 EditView:=Editor.EditViews[i];

 //使用IOTASourceEditor的 EditViews[]属性得到一个IOTAEditView

 EditWriterPos:=EditView.Position;

 //使用IOTAEditView的Position属性最终得到一个IOTAEditPosition

 EditWriterPos.InsertText('{///  This is add by the OTATest of hk.barton,enjoy days!  ///}');

 //IOTAEditPosition的InsertText方法向当前光标位置插入一行代码,这里是一行注释。

end;

 

procedure TNTATest.AboutForm(sender: TObject);

//一个简单的关于对话框,注意参数中的IDEHandle

begin 
   messagebox(IDEHandle,'This is a test of OTA write by hk.barton','hkTest',MB_ICONINFORMATION);
end; 

procedure TNTATest.ReMoveMenu;

//卸载菜单

begin 
   if assigned(NewMenu) then NewMenu.Free;
end; 


destructor TNTATest.Destroy;

begin

 MyNTATest.ReMoveMenu;

 if ImageIndex1<>-1 then

 //如果在前面加载图标的工作出现异常就不释放图标,否则会释放到delphi本身使用的图标

  MyNTATest.FImageList.Delete(MyNTATest.ImageIndex1);

 inherited;

end; 

initialization

//在组件第一次被安装时创建了TNTATest

 MyNTATest:=TNTATest.Create;

finalization

//在组件被卸载时释放了MyNTATest

 MyNTATest.Free;

end.

请注意上面代码中的注释。单就这个例子可能并没有多少用处,然而只要你稍微扩展就可以让这个例子有一点实际用处,你可以加入很多菜单项,每一个项对应一些用户常用的但烦琐的代码,这样就可以免去在开发中输入同样代码的烦琐了,甚至你还可以设置快捷键,也可以做一个设置窗口允许用户自己设置需要的代码和动态的添加菜单项目。当然要完成更复杂的插件你还需要其他的OTA知识,我会在以后的专栏文章中不连续的介绍这些。这次就写到这里,我已经在文章开始的地方推荐了一些学习OTA的资料,另外如果需要这个例子的全部代码,请给我来信索取:hk.barton@sohu.com。 


 

10、使用Open Tools API提升Delphi开发效率 本文详细介绍了如何使用Delphi的Open Tools API进行组件编辑器注册、IDE服务获取、项目和模块处理,以及编写各种类型的向导(如自定义向导、DLL向导、表单向导和DDG搜索向导)。通过这些功能,开发者可以显著提升开发效率和灵活性,并实现对Delphi IDE的深度定制。 阅读详情

相关推荐

47、使用Open Tools API增强Delphi IDE

本文详细介绍了如何使用Delphi的Open Tools API增强IDE功能,包括注册自定义组件编辑器、获取IDE服务、处理项目和模块的基本与高级操作。通过这些技术,开发者可以更灵活地定制和集成开发环境,提高开发效率和项目管理能力。

g8f9d0s1a2的博客 82

Delphi Open Tools Api实例研究(二)

Delphi Open Tools Api实例研究(二)先行知识:Delphi/接口/DLL/COM(了解)难度:★★☆☆☆     在开始之前先说一些题外话,这段时间一直很忙(马上就要期末考试,而且最惨的是现在正在忙着准备即将到来的英语4级考试),所以自己也不知道这篇文章够不够份量。这篇文章的内容可能不是太多,但我还是抽时间把它写了出来作为我们的Delphi Open Tools

hkbarton的专栏 1608

BCB与Delphi中ToolsAPI的使用与实践

Delphi编译器是一种高级语言编译器,它将Object Pascal语言的源代码(.pas文件)转换成可执行的机器代码。编译过程涉及几个关键步骤,包括词法分析、语法分析、语义分析、中间代码生成、优化和目标代码生成。词法分析(Lexical Analysis):编译器读取源代码,将其分解成一系列的标记(tokens),如标识符、关键字、运算符等。语法分析(Syntax Analysis):分析标记流,以确定源代码的语法结构是否符合语言的语法规则。

weixin_42527589的博客 1106

Delphi Open Tools API - Simple Wizard

    之前向大家简单的介绍了Open Tools API,现在我们就要亲自动手编写一个简单的Wizard,来体验Open Tools API的魅力所在。     在Delphi6中,不再推荐大家使用ExptIntf单元中的TIExpert类做为我们自己编写的Wizard的基类,而是改用TInterfacedObject做为其基类,并实现ToolsAPI单元中的一个或我个接口。    编写

Chris Mao的专栏 2358

Delphi中的IDE--ToolsAPI中文帮助

Delphi中的IDE--Tools API中文帮助

ToolsAPI编程指南

微软使用VBA宏来来拓展其开发平台的功能,BCB必须通过 ToolsAPI来拓展气开发平台,包括Borland C++Builder Borland Delphi 等!

附录A 使用OPENTOOLS API的Delphi扩展示例

附录A  使用OPENTOOLS API的Delphi扩展示例 附录A与第11章的内容前后承继。阅读第11章之后,您已经了解了创建定制组件的大部分知识。附录A也很重要,它示范了如何创建组件编辑器以及使用OpenTools API对Delphi自身进行扩展。二者分属不同的主题:一个与组件相关,另一个则是要扩展Delphi。之所以将二者放到附录中,是因为它们没有其他技术那样常用。但要用到二者的时

ksrsoft的专栏 1675

ToolsAPI.dcu ToolsAPI.pas BCB Delphi

ToolsAPI.dcu ToolsAPI.pas BCB Delphi 编译 cnwizards cnvcl 用到的包

Delphi Open Tools Api实例研究(一) (转)

Delphi Open Tools Api实例研究(一) (转)[@more@]Delphi Open Tools api实例研究(一)XML:namespace prefix = o ns = "urn:schemas-mic...

csd3176的博客 198

扩展Delphi的IDE--ToolsAPI帮助中译版

Delphi的IDE扩展是一般程序员很少涉足的领域,不管是网上还是书店里,这方面的资料都是鲜有所见。Delphi7自带的帮助文件是我们最容易找到的资料,为了方便CnPack开发组成员以及对IDE扩展感兴趣的朋友对这一领域有更多的认识,我花了点时间把Delphi7中IDE扩展部分的帮助翻译成中文发布,希望对大家有所帮助。

【保研面试】线性代数面试复习

线性相关和无关 有向量组A,a1,a2…an , 如果存在不是全为0的k1,k2…kn,满足 a1 * k1 + a2 * k2… an * kn = 0 则向量组A称为线性相关(可以跟向量组A共面联系,即可以通过几个向量,表示出另外几个向量,故称为线性相关) 极大线性无关组 设有向量组A a1,a2…an(本身为线性相关) :若选出r个向量,满足以下条件 (1)向量组 r : 线性无关; (2) 向量组A中任意r+1个向量(若有的话)都线性相关, 则向量组r 是向量组A的一个极大线性无关组(简称为

云端筑梦师 6311

Delphi Open Tools API - Menu Wizard

在Delphi中编写一个Menu Wizard也是相当的简单,在实现IOTAWizard接口的同时,也实现IOTAMenuWizard接口即可。

Chris Mao的专栏 1383

服务器被黑?快速检测和识别系统中的恶意进程

在管理服务器时,检测和识别系统中的恶意进程至关重要。本文介绍了使用 `ps`、`top`、`htop` 等系统监控工具,分析日志文件,以及使用 `chkrootkit` 和 `rkhunter` 等安全工具的方法。通过这些步骤,可以有效地检测和处理恶意进程,确保系统的安全和稳定。

_midnight的博客 1416

Delphi Open Tools API 浅探 - 元件编辑器

Delphi Open Tools API 浅探 - 元件编辑器savetime2k@yahoo.com  2004.1.28http://savetime.delphibbs.com今天开始学习元件编辑器,感觉比属性编辑器简单许多,但还是遇到了一些疑问。如果你能解答文中记录的问题,请告诉我答案,谢谢!目 录=============================================

乱炖 1486

Advanced Installer打包避坑指南:如何正确配置64位系统下的Java环境与注册表条件(以15.7版本为例)

本文详细解析了使用Advanced Installer 15.7版本在64位系统下打包Java应用时的常见问题与解决方案。重点介绍了注册表重定向机制、Java环境检测的双保险策略、环境变量设置的隐藏坑以及权限管理的进阶技巧,帮助开发者避免安装包在用户机器上无法运行的幽灵问题。

weixin_28676289的博客 322

Linux 命令之 locale -- 设置和显示程序运行的语言环境

文章目录命令介绍locale 设置规则使用详解(一)查看当前 locale 设置(二)查看当前系统所有可用 locale(三)设置系统的 locale 命令介绍 locale 是 Linux 系统中多语言环境的设置接口,在 Linux 中,使用 locale 命令来设置和显示程序运行的语言环境,locale 会根据计算机用户所使用的语言,所在国家或者地区,以及当地的文化传统定义一个软件运行时的语言环境。 通过 locale 来设置程序运行的不同语言环境,locale 由ANSI C提供支持。locale 的

liaowenxiong的博客 3万+
上一篇: 一些关于OTA的相当不错的网站和资料
下一篇: Delphi Open Tools Api实例研究(二)
SafeF8
博客等级 码龄22年 10粉丝 104原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值