科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道使用 C# 进行 Outlook 2003 编程的简介 6

使用 C# 进行 Outlook 2003 编程的简介 6

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

需要注意的主文件被命名为 Connect.cs.在这里将找到一个名为 Connect 的类类型,如下所示(为了简洁起见,删除了 XML 代码注释):

作者:中国IT实验室 来源:中国IT实验室 2007年9月8日

关键字: C#

  • 评论
  • 分享微博
  • 分享邮件
分析连接类类型

  需要注意的主文件被命名为 Connect.cs.在这里将找到一个名为 Connect 的类类型,如下所示(为了简洁起见,删除了 XML 代码注释):

 [GuidAttribute("762B03FF-52D0-4735-9D2B-4DE32DB9393E"),
ProgId("EMailStatsAddIn.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2
{
  public Connect(){}
  public void OnConnection(object application,
    Extensibility.ext_ConnectMode connectMode,
    object addInInst, ref System.Array custom)
  {
    applicationObject = application;
    addInInstance = addInInst;
  }
  public void OnDisconnection(Extensibility.ext_DisconnectMode
    disconnectMode, ref System.Array custom) {}
  public void OnAddInsUpdate(ref System.Array custom){}
  public void OnStartupComplete(ref System.Array custom){}
  public void OnBeginShutdown(ref System.Array custom){}
  private object applicationObject;
  private object addInInstance;
}

  需要注意的第一点是,该类具有 [Guid] 和 [ProgId] 属性,这些众所周知的属性值用来标识 COM 类。生成托管代码库时,您可能想知道为什么需要将程序集注册为由 COM 使用。请回忆,大多数能够访问外接程序类型的宿主都被编写为加载 COM 服务器(而不是 .NET 程序集)。因此,为了启用互操作,就要为 Connect 类型提供所需的 COM 命名约定(当然,GUID 值将是不同的)。

  接下来要注意的是,Connect 类型没有扩展以外接程序为中心的基类,而只是从 System.Object 派生。使共享外接程序具有唯一性的原因是它实现了一个关键接口:Extensibility.IDTExtensibility2.实际上,Connect 类的成员只是接口合约的基本实现。

  最后,请注意 Connect 类定义了两个私有成员变量:

 private object applicationObject;
private object addInInstance;

  第二个成员变量 (addInInstance) 表示由宿主分配和插入的当前外接程序的实例。applicationObject 成员变量表示对宿主应用程序的引用。

  假设共享外接程序可以插入到很多不同的应用程序(Outlook 2003、Visual Studio.NET 2003、各种 Microsoft Office 应用程序等等)中,那么将 applicationObject 定义为一般 System.Object.但是,假如我们的外接程序只是为了由 Outlook 使用,则将 applicationObject 定义为 Microsoft.Office.Interop.Outlook.Application 类型:

 // Don't forget to reference the Outlook interop assembly!
using Microsoft.Office.Interop.Outlook;
...
public class Connect : Object, Extensibility.IDTExtensibility2
{
  ...
  // Change to a strongly typed Outlook Application type.
  // private object applicationObject;
  private Microsoft.Office.Interop.Outlook.Application
    applicationObject;
  private object addInInstance;
}

  使用该初始代码更新,让我们检查 IDTExtensibility2 接口提供的功能。

  IDTExtensibility2 接口的角色

  IDTExtensibility2 接口类型定义了在外接程序生命周期的各个阶段宿主应用程序所调用的五个方法。下面是正式定义:

 public interface IDTExtensibility2
{
  void OnAddInsUpdate(ref Array custom);
  void OnBeginShutdown(ref Array custom);
  void OnConnection(object Application, ext_ConnectMode ConnectMode,
    object AddInInst, ref Array custom);
  void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom);
  void OnStartupComplete(ref Array custom);
}

  OnConnection() 方法

  第一个需要注意的方法是 OnConnection(),外接程序连接到宿主时将调用该方法。第一个参数表示宿主应用程序本身(Visual Studio.NET、Microsoft Outlook 等)。第二个参数是类型 ext_ConnectMode 的枚举,它表示宿主具体怎样 加载外接程序类型。ext_ConnectMode 枚举定义以下值(其中,ext_cm_CommandLine 和 ext_cm_Solution 不会被 Outlook 2003 使用):

 public enum ext_ConnectMode
{
  // Add-in loaded after host.
  ext_cm_AfterStartup = 0;
  // Add-in loaded from command line.
  ext_cm_CommandLine = 3;
  // Add-in loaded indirectly from host.
  ext_cm_External = 2;
  // Add-in loaded by a VS.NET solution which required it.
  ext_cm_Solution = 4;
  // Loaded when host starts-up.
  ext_cm_Startup = 1;
  // Loaded for very first time after installed.
  ext_cm_UISetup = 5;
}

  第三个参数是一个对象,该对象表示由 IDE 宿主的外接程序实例,其中最后一个参数类型为 System.Array,该参数表示用户提供的任何自定义数据(在我们的示例中可以被忽略)。

  生成的代码很简单。但是,假如已经定义了强类型的 applicationObject 成员变量,则现在需要使用显式转换来分配该变量:

 public void OnConnection(object application,
  Extensibility.ext_ConnectMode connectMode,
  object addInInst, ref System.Array custom)
{
  applicationObject =
    (Microsoft.Office.Interop.Outlook.Application)application;
  addInInstance = addInInst;
}

  我们需要对 OnConnection() 方法再有一个初始更新。按照 Knowledge Base article,OnConnection() 的整洁且正确的实现应当执行运行库测试来确定连接模式是否不同于 ext_ConnectMode.ext_cm_Startup,如果是这样,则将传入的 System.Array 转发给 OnStartupComplete() 的外接程序实现:

 public void OnConnection(object application,
  Extensibility.ext_ConnectMode connectMode,
  object addInInst, ref System.Array custom)
{
  // Cast to a strongly typed Application.
...
  // If we are not loaded upon startup, forward to OnStartupComplete()
  // and pass the incoming System.Array.
  if(connectMode != ext_ConnectMode.ext_cm_Startup)
  {
    OnStartupComplete(ref custom);
  }
}

  OnDisconnection() 方法

  当外接程序与宿主断开时(通常通过添加/删除外接程序对话框或在宿主关闭时)将调用该方法。断开模式由类型 ext_DisconnectMode 的第一个参数表示:

 public enum ext_DisconnectMode
{
  ext_dm_HostShutdown = 0;
  ext_dm_SolutionClosed = 3;
  ext_dm_UISetupComplete = 2;
  ext_dm_UserClosed = 1;
}

  向导生成的 OnDisconnection() 实现当前为空。很明显,这是外接程序执行任何清理操作的地方,为了成功关闭,外接程序可能需要执行该操作。再次,按照 Knowledge Base article,该方法的整洁且正确的实现应当对连接模式进行测试(这次针对除了 ext_DisconnectMode.ext_dm_HostShutdown 以外的任何内容),并将传入的 System.Array 转发给我们的 OnBeginShutdown() 的实现:

 public void OnDisconnection(Extensibility.ext_DisconnectMode
  disconnectMode, ref System.Array custom)
{
  if(disconnectMode !=
    ext_DisconnectMode.ext_dm_HostShutdown)
  {
    OnBeginShutdown(ref custom);
  }
  applicationObject = null;
}

  OnAddInsUpdate() 方法

  如果最终用户在宿主中插入或删除外接程序,将调用 OnAddInsUpdate() 方法(可以用 Application.COMAddins 属性在运行时获得当前列表)。如果需要在最终用户添加或删除新外接程序时执行任何特殊的过程,这里将是执行该操作的地方。自动生成的实现当前为空,并且可以保留该状态。

  OnStartupComplete() 方法

  宿主应用程序完成加载之后,将调用该方法。这时,所有宿主资源均可供外接程序使用。这是为外接程序类型构造 UI 的理想地方,因为可以安全获得 Explorers 和 Inspectors 集。

  OnBeginShutdown() 方法

  最后介绍 OnBeginShutdown(),它表示宿主正处于关闭过程中(正好在调用 OnDisconnection() 方法之前)。这时,仍然可以访问宿主应用程序,所以,这是删除插入到活动资源管理器中的任何 UI 小部件的理想地方。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章