Delphi Open Tools Api实例研究(一)

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

先行知识:Delphi/接口/VCL组件包/COM(了解)

难度:★★☆☆☆

 

在这篇文章正式开始以前,首先向大家道歉。因为这个月的专栏文章本该很早就发布,但由于一些事情所以一直推迟到现在,并且这个月也只发布了这么一篇。另外,关于这篇文章我觉得我应该感谢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运行中如同安装组件一样的进行安装。我们的例子将向delphi的主菜单中添加一个有两项的菜单(名字叫做hk.barton),点击第一项将向当前工程的第一个代码编辑器的代码中插入一句指定的代码,第2项简单的显示一个关于信息。当你不想使用这个菜单的时候只需要象一般组件的卸载一样将其卸载就可以了。最先还是来看看组件包的项目文件,如果大家看过我之前的关于VCL的文章就应该很熟悉了:

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的资料。

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

DELPHI7实现XP菜单风格

步骤八:选择第一个TActionBarItem, 设它的ActionBar属性为ActionMainMenuBar,选第二个TActionBarItem,设它的ActionBar属性为ActionToolBar.步骤四:把Additional面板上的ActionToolBar组件加到PageScrooler组件上(注意放在PageScroolerh 上)步骤二:把Additional面板上的ActionMainMenuBar组件加到CoolBar组件上.(注意一定要放在CooBar 组件上)

男神的专栏 698

Delphi开发API方面技巧

内容: 获得特殊文件夹名称 控制任务栏 控制Windows 运行外部应用程序 获得与windows环境有关的信息 模拟鼠标事件 获取驱动器相关信息 判断是否按下了Alt、Ctrl、Shift键 SendMessage函数的妙用 查阅可视窗口标题 窗体上坐标映射到屏幕 显示/隐藏桌面程序图标 获取和设置鼠标指针位置 如何增加和清空文档菜单 显示系统的About对话框 你的程序中使用系统图标 提取文件的Icon

Delphi ActionList详解

一个友好的用户界面,必须具有下拉菜单,弹出菜单,工具条和快捷键。同样一个功能,程序员可能要提供几种操作方式,如文本拷贝,菜单命令 &Copy,快捷键Ctrl+C,工具条上的拷贝按钮,都是程序员提供给用户的操作,可以大大方便了不同层次的用户。但是,多增加一种操作方式,就意味着增加响应事件的代码,还有,实现统一功能的多个操作必须一致,如剪切板上不为空的时候,菜单命令,快捷键,按钮,都是可以选择的Ena

苏生-苏米沿的专栏 1802

Delphi中的IDE--ToolsAPI中文帮助

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

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

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

Action高级开发

Action高级开发 Action开发篇 在讨论Action的开发前,我想先讨论一下为什么要使用TActionList及TAction。从Delphi 4开始Borland提供了TActionList控件,ActionList提供了一种全新的设计用户界面交互模式的方法。传统的事件模式无法解决命令状态更新的问题,因为任何情况下命令都是有效的。Delphi 4通过使用ActionList及...

weixin_30278311的博客 231

ToolsAPI编程指南

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

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

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

csd3176的博客 198

ToolsAPI.dcu ToolsAPI.pas BCB Delphi

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

免费搞定DWG转DXF:ODA File Converter保姆级配置指南(附常见报错解决)

本文详细介绍了如何使用ODA File Converter免费工具实现DWG到DXF的格式转换,包括环境配置、命令行参数解析、编程集成方案及常见问题解决。特别针对网络访问异常、参数配置等实际痛点提供应对策略,帮助用户高效完成工程设计文件的格式转换。

weixin_29291185的博客 6008

Delphi Open Tools Api实例研究(二)

Delphi Open Tools Api实例研究(二) 先行知识:Delphi/接口/DLL/COM(了解) 来自:http://dev.youkuaiyun.com/develop/article/21/21725.shtm难度:★★☆☆☆       在开始之前先说一些题外话,这段时间一直很忙(马上就要期末考试,而且最惨的是现在正在忙着准备即将到来的英语4级考试),所以自己也不知道这篇文章够不够份量。这

简简单单 2000

silvaco(TCAD)击穿特性仿真,的不收敛问题

在silvaco仿真学习过程中,最近这段时间一直有一个很大的问题困扰着我,那就是我在仿真击穿特型曲线的过程中,在电压加到后期比较大的情况下,往往会出现仿真不收敛的情况,正常情况下器件的击穿应该在一个外加偏压上,电流出现迅速的上升,这才是击穿的定义,但是我仿真的过程中程序跑到一个较大的电压时,器件出现击穿,我观察电压电流曲线,在击穿电压(程序报告的)电流并没有出现迅速的变化,类似于下图这种形式。(2)解决方法,将初始电压调整到合适的值,这个值可能是更大的也可能是更小的,要注意多多尝试。

zm19992533002908的博客 4946

Delphi Open Tools API - Simple Wizard

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

Chris Mao的专栏 2358

基于verilog的16QAM调制

思路1:正交调幅法——实现16QAM调制,可以理解为时相位相差90度的两个正弦波的4PAM叠加。 4比特输入经过2->4进制转化得到两路2比特输入,然后分别经过4PAM后叠加所得输出即为16QAM调制结果。 具体程序稍后编写。 思路2:复合相移法——可以借助前面编写的QPSK,相当于两路幅度不同的QPSK的叠加,比如幅度分别取1和3 。 思路1正交调幅法的设计方案: 两正弦波相位差...

weixin_30725467的博客 2929

AirSim中图像API的应用

解析Airsim图像获取保存的api

fegxg的博客 1604
上一篇: Itext使用说明
下一篇: Delphi Open Tools Api实例研究(二)
wangphoenix
博客等级 码龄24年 3粉丝 42原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值