2007年7月11日星期三

abBars代码解读之——Visual Studio的自动化接口

Microsoft的Visual Studio开发工具为软件开发人员提供了强大的功能,通过集成开发环境(IDE)的构建平台提供的菜单和工具条,开发人员可以生成项目,编写代码,调试直到最终生成应用程序。除此之外,Visual Studio还提供了一套完整的自动化对象,通过操作这些自动化对象提供的方法,开发人员在不使用菜单和工具条的情况下也能够完成诸如打开文件、激活窗口或改变窗口大小等操作。Visual Studio提供了两种方法让用户控制集成开发环境和它的自动化组件对象,一种是使用宏(Macros),另一种是使用内置插件(Add-ins)。本文主要是介绍内置插件(Add-ins)方面的内容。
    每一个自动化对象都代表了集成开发环境的一个构件或相关的一组构件。例如Document代表一个打开的文档,而Documents对象则代表所有打开的文档,同样,一个Window对象代表一个打开的窗口,Windows对象代表所有打开的窗口。使用内置插件可以在脱离IDE的情况下打开一个项目。修改项目中的文件甚至重新Build这个项目。使用内置插件还可以向IDE添加实用的命令,在工具条上创建按钮,扩展IDE的功能。
    IDSAddIn接口是Visual Studio定义的插件接口,Visual Studio只是定义了这个接口,一个内置插件就是一个IDSAddIn接口的实现,也就是说,一个内置插件就是一个COM对象,它至少应该实现一个 IDSAddIn接口。使用VC的Add-ins向导生成的内置插件代码核心就是一个CDSAddIn类:

class CDSAddIn : public IDSAddIn,
  public CComObjectRoot,public CComCoClass<CDSAddIn, &CLSID_DSAddIn<

IDSAddIn接口其实只有两个方法,分别是:

IDSAddIn::OnConnection       插件被装载
IDSAddIn::OnDisconnection    插件被卸载

插件工作的过程是这样的,当IDE启动一个插件时,就按照IDSAddIn接口的约定调用插件的coclass实现的OnConnection,并传递一个Application参数给插件,插件的OnConnection就完成插件的初始化。并通过这个 Application对象查询IDE支持的其他自动化对象,通过这些对象完成特定的任务。一个内置插件典型的任务就是向系统的Commands对象注册一个命令并在工具条上创建一个按钮。当系统要卸载一个内置插件时就会调用相应的OnDisconnection,插件应该利用这个机会释放已经申请的系统资源,从系统的Commands对象中注销已经注册的命令,同时删除添加在工具条上的按钮。从这个过程可以看出,虽然插件的加载和释放都是被动进行的,但是通过实现自定义的OnConnection和OnDisconnection接口函数,插件可以完成自己定制的初始化和销毁任务,这很像是COM事件的回调过程,从接口函数的名字也可以看出一些倪端,接口函数的名字都是以"On"开头,这通常是COM体系中事件接口的声明方式。图(1)表示了内置插件、IDSAddIn接口和实现类之间的关系:


图1. 插件组件、IDSAddIn接口和实现类之间的关系

    Visual Studio的IDE通过IDSAddIn::OnConnection接口函数将一个很重要的参数传递给插件,这个参数就是一个Application 对象。Application对象对应的是整个Visual Studio IDE 的实例,简单点讲,可以理解为一个Application就是一个打开的VC集成开发环境。Application对象是整个Visual Studio内置组件的核心组件,通过Application对象可以查询整个Visual Studio IDE的所有内置对象,并通过这些内置对象控制Visual Studio。以下代码演示了在不打开VC的IDE的情况下打开一个VC的工作区并执行Rebuild All命令编译这个工作区的所有项目:

//伪代码,不可直接编译
#import "....\devshl.dll"

IApplicationPtr pApp;
pApp.CreateObject(_T("MSDEV.Application"));
if(pApp != NULL)
{
  pApp-<RebuildAll();
}

    内置插件通过IDSAddIn::OnConnection接口函数接口函数获得一个当前集成开发环境的Application对象,插件随后的所有工作都是围绕着这个Application对象进行的,CDSAddIn负责保存这个Application对象。Visual Studio的内置COM对象接口是一个比较复杂的接口模型,图(2)就是这些内置接口的关系图:

图2. Visual Studio的内置COM对象接口关系图

    下面就以TabBars的自动添加格式化函数说明功能的部分代码为例,演示如何通过Application对象实现在当前文档中插入文字内容:

CComPtr<IDispatch< pDispDoc;
CComQIPtr<ITextDocument, &IID_ITextDocument< pDoc;
//m_pApplication是CDSAddIn保存的一个Application对象
m_pApplication-<get_ActiveDocument(&pDispDoc);
pDoc = pDispDoc; //隐式的接口查询
pDispDoc = NULL; //Release it

if(pDoc)
{
  CComPtr<IDispatch< pDispSel;
  CComQIPtr<ITextSelection, &IID_ITextSelection< pSel;
  CComBSTR bstr;
  CString strText;

  pDoc-<get_Selection(&pDispSel);
  pSel = pDispSel; // 查询ITextSelection对象
  pDispSel = NULL;
  hr = pSel-<get_Text(&bstr); //得到当前选择的文字
  if(SUCCEEDED(hr))
  {
    strText = bstr;
    strText.Replace(_T("\t"),_T(" ")); //将\t替换成空格
    bstr = strText;
    pSel-<put_Text(bstr);//写入document
  }
}

    了解了Visual Studio的自动化接口以及如何使用这些接口之后,就可以大致了解TabBars是如何工作的,随后的代码解读将重点介绍每个TabBars的功能是如何实现的,并结合这些功能讲解Visual Studio内置COM对象接口的用法。

您认为本文应该得         打印| 收藏|讨论|投诉

暂无图片

网名oRbIt,1996年开始编程,1999年创建星轨工作室(Orbit Studio),创作了Source Insight外挂插件"TabSiPlus"、"Winmsg消息精灵"、"TabBar Addin for VC"和"aClock 桌面时钟"等软件。目前在中兴通讯股份有限公司上海研发中心工作,从事以太网光接入产品(EPON&GPON)的开发与研究工作。



--
一步一步教你从互联网赚钱 http://www.zqzn.com/index.asp?rid=key480769
投资理财 http://li-cai.blogspot.com/

没有评论: