原文:VSTO之旅系列(五):创建Outlook解决方案

本专题概要

  • 引言
  • Outlook对象模型
  • 自定义Outlook窗体
  • 小结

一、引言

  在上一个专题中,为大家简单介绍了下如何创建Word解决方案的,所以本专题中将为大家介绍下Outlook相关的内容。我们从Visual Studio 2010 中Office节点下的模板中我们可以看到,Outlook只有外接程序的模板,并没有提供像Word或Excel这样的文档级的模板,所以VSTO没有为Outlook解决方案创建宿主项和宿主控件(Excel和Word中VSTO都为他们提供了宿主项和宿主控件,因为这些控件是文档级别的。对于宿主控件和宿主项的具体内容可以参考本系列的专题一)。为了能够更好地创建Outlook的解决方案,下面就具体介绍下Outlook对象模型。

二、Outlook对象模型

2.1 Application 对象

Application对象代表着Outlook应用程序,并且也是Outlook对象模型里的顶层对象(这点和Word和Excel是一样的)。在VSTO项目中要获得该对象的实例同样可以通过ThisAddIn类的Application字段来实现,具体代码为:Globals.ThisAddIn.Application或This.Application

2.2 NameSpace对象

Application对象的Session属性返回一个NameSpace对象,Session从字面上看是会话的意思,在Web开发中,我们可以从Session对象中获得保存的信息,同样,我们可以通过NameSpace对象来访问Outlook数据,比如当我们想获得收件箱里邮件数量时,此时就可以用到NameSpace对象,具体代码如下:

  // 获得收件箱文件夹
Outlook.MAPIFolder Inbox = this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
// 获得收件箱中邮件数量
int mailnumbers = Inbox.Items.Count;

2.3 Explorer对象

Explorer对象是显示Outlook中文件夹内容的窗口。文件夹包含项,例如邮件项,通俗点说,我们点击Outlook中的邮件或日历或联系人时,出现的窗口就是一个Explorer对象。

2.4 Inspector对象

Inspector对象是显示Outlook中每个项(例如单个电子邮件项、单个联系人项)的窗口。看到这里,有些朋友肯定会把Explorer对象与Inspector对象弄混淆,相信通过下面的图大家肯定可以完全明白两者的区别:

2.5 Outlook文件夹,即MAPIFolder对象

Outlook文件夹用来存储项(即邮件项,联系人项,任务项等),在Outlook中你可以创建自己的文件夹,然而Outlook中也提供了一些默认的文件夹。上面的这段代码: this.Application.Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox); 就是获得收件箱文件夹,如果你需要获得其他文件夹,可以通过改变OlDefaultFolders枚举值来获得。

2.6 Outlook项

Outlook里的项包含在文件夹里的。我们可以通过下面的代码来创建一个邮件项,如果要获得其他的Outlook项,可以通过修改Outlook.OlItemType枚举值来实现

 // 创建邮件项
Outlook.MailItem mailItem = (Outlook.MailItem)this.Application.CreateItem(Outlook.OlItemType.olMailItem);

三、自定义Outlook窗体

  介绍了Outlook的这么多对象的,大家肯定很迫不及待地想知道使用VSTO的技术可以为Outlook实现什么样的功能呢?下面就用VSTO的技术来自定义Outlook的联系人窗体,在很多时候,我们都希望联系人的窗体中有关于父母的联系方式,然后在现有的Outlook界面中却没有这样的字段来给我们填写的,所以这里通过Form Region 的方式来实现自定义联系人窗体,我们需要在联系人窗体中加入输入父母姓名和联系方式的控件。

首先,我们需要创建Outlook窗体区域,创建步骤如下:

  1. 右键项目,选择添加——>新建项目——>Outlook窗体区域
  2. 选择”设计新的窗体区域“选项

  3. 窗体区域类型选择相邻,即把自定义的窗体附加到页面的底部。

4. 为窗体区域输入一个名字,并且设定在编辑模和阅读模式和中都显示窗体区域。

  5. 把我们的窗体区域嵌入在联系人窗体中。

完全以上一系列的步骤之后,VS会帮我们自动创建一个空的窗体区域,如果我们想修改刚才创建的窗体区域的设置,我们可以通过它的属性窗口中进行修改。

创建完窗体区域之后,我们就需要在窗体区域中添加我们需要自定义的控件了,这里的设计界面如下:

设计完界面之后,最后就是实现我们的后台逻辑了,即在后台写代码来完成我们所需要实现的功能。具体后台代码如下(因为代码注释中都有解释,大家不懂实现过程可以看代码注释):

 // 对应的联系人(Contact)对象
private Outlook.ContactItem contactItem; // 自定义属性对象
private Outlook.ItemProperty MotherName = null;
private Outlook.ItemProperty MotherTelNumber = null;
private Outlook.ItemProperty FatherName = null;
private Outlook.ItemProperty FatherTelNumber = null;
// 在显示窗体区域之前发生。
// 使用 this.OutlookItem 获取对当前 Outlook 项的引用。
// 使用 this.OutlookFormRegion 获取对窗体区域的引用。
private void ContactFormRegion_FormRegionShowing(object sender, System.EventArgs e)
{
// 获得FormRegion所对应的Contact对象
contactItem = this.OutlookItem as Outlook.ContactItem; // 在从自定义属性中取出值时,首先确保自定义属性不为空。
EnsureProperties(); // 从联系人的自定义属性中取出值为控件赋值
txbMotherName.Text = MotherName.Value;
txbFatherName.Text = FatherName.Value;
txbMotherTel.Text = MotherTelNumber.Value;
txbFatherTel.Text = FatherTelNumber.Value;
} // 在关闭窗体区域时发生。
// 使用 this.OutlookItem 获取对当前 Outlook 项的引用。
// 使用 this.OutlookFormRegion 获取对窗体区域的引用。
private void ContactFormRegion_FormRegionClosed(object sender, System.EventArgs e)
{
// 释放对象
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(contactItem);
contactItem = null;
} // 确保所有自定义属性不为空
private void EnsureProperties()
{
EnsureItemProperty(ref MotherName, "montherName", Outlook.OlUserPropertyType.olText);
EnsureItemProperty(ref FatherName, "fatherName", Outlook.OlUserPropertyType.olText);
EnsureItemProperty(ref MotherTelNumber, "motherTelNumber", Outlook.OlUserPropertyType.olText);
EnsureItemProperty(ref FatherTelNumber, "fatherTelNumber", Outlook.OlUserPropertyType.olText);
} // 确保项目属性不为空引用
private void EnsureItemProperty(ref Outlook.ItemProperty property, string name, Outlook.OlUserPropertyType propertyType)
{
// 如果自定义属性为空时
// 首先从联系人项关联的属性集合中获得属性对象
// 如果项目集合中还不存在该属性时,就把该属性名称添加进ItemProperties集合中
if (property == null)
{
property = contactItem.ItemProperties[name];
if (property == null)
{
property = contactItem.ItemProperties.Add(name, propertyType);
}
}
} // 父亲名字修改事件
private void txbFatherName_TextChanged(object sender, EventArgs e)
{
// 保存值到自定义的属性中
FatherName.Value = txbFatherName.Text;
} // 父亲的电话号码修改事件
private void txbFatherTel_TextChanged(object sender, EventArgs e)
{
// 保存值到自定义的属性中
FatherTelNumber.Value = txbFatherTel.Text;
} // 母亲名字修改事件
private void txbMotherName_TextChanged(object sender, EventArgs e)
{
// 保存值到自定义的属性中
MotherName.Value = txbMotherName.Text;
} // 母亲的电话号码修改事件
private void txbMotherTel_TextChanged(object sender, EventArgs e)
{
// 保存值到自定义的属性中
MotherTelNumber.Value = txbMotherTel.Text;
}

从上面的代码中可以看出,主要的实现思路是——初始化联系人窗口,从自定义属性中获取值来初始化窗体中控件的值,如果自定义属性不存在时,此时就需要把自定义属性添加进ItemProperties集合中来确保自定义属性不为空,如果自定义属性存在,则直接中自定义属性中获取值来初始化窗体中的控件。最后注册窗体中每个控件的修改事件,把控件中值的修改保存到自定义属性中,这样以便下次打开联系人时可以获得修改过的数据

这样我们的设计就完成了,接下来看看程序的运行结果吧(按F5 运行该程序):

运行出现的第一个窗口为:

点击新建联系人之后,出现编辑联系人窗体,此时在窗体中可以看到我们自定义的窗体:

输入联系人的相关信息,点击保存并关闭按钮,然后我们再打开该联系人,修改"父亲电话"为 ”123456“(之前是123456789),点击保存并关闭按钮,当我们下次再打开该联系人时,此时可以获得修改后的数据信息:

这样就成功完成了我们开始所说的需求,当然这个还有很多不足的地方,比如没有对电话号码进行验证(如在电话号码文本框中输入中文或者不存在的号码,或者不是11位的号码等情况进行讨论)。

四、小结

  到这里,本专题的内容就介绍完了,希望通过本专题可以帮助大家理解如何用VSTO技术来自定义我们的Outlook窗体和我们的Outlook界面(自定义Outlook界面和自定义Excel界面很类似,具体操作可以参考专题三)。在下一个专题中将为大家介绍如何实现Office的自动化编程。

本专题源码:http://files.cnblogs.com/zhili/VSTOOutlook.zip

VSTO之旅系列(五):创建Outlook解决方案的更多相关文章

  1. VSTO之旅系列(二):创建Excel解决方案

    原文:VSTO之旅系列(二):创建Excel解决方案 本专题概要 引言 创建VSTO项目 Excel对象模型 创建Excel外接程序 创建Excel文档级自定义项 小结 一.引言 也许很多朋友都没有听 ...

  2. VSTO之旅系列(四):创建Word解决方案

    原文:VSTO之旅系列(四):创建Word解决方案 本专题概要 引言 Word对象模型 创建Word外接程序 小结 一.引言 在上一个专题中主要为大家介绍如何自定义我们的Excel 界面的,然而在这个 ...

  3. VSTO之旅系列(三):自定义Excel UI

    原文:VSTO之旅系列(三):自定义Excel UI 本专题概要 引言 自定义任务窗体(Task Pane) 自定义选项卡,即Ribbon 自定义上下文菜单 小结 引言 在上一个专题中为大家介绍如何创 ...

  4. VSTO之旅系列(一):VSTO入门

    原文:VSTO之旅系列(一):VSTO入门 引言: 因为工作的原因,这段时间一直在看VSTO的相关的内容的,因此希望通过这个系列来记录下我学习的过程和大家分享Office开发的相关知识,希望以后有朋友 ...

  5. VSTO学习(六)——创建Outlook解决方案

    本专题概要 引言 Outlook对象模型 自定义Outlook窗体 小结 一.引言 在上一个专题中,为大家简单介绍了下如何创建Word解决方案的,所以本专题中将为大家介绍下Outlook相关的内容.我 ...

  6. VSTO学习(三)——创建Excel解决方案

    四.创建Excel外接程序介绍完了Excel对象模型之后,我们就可以利用这些对象来对Excel文档进行操作了,下面就创建一个简单的Excel外接程序的.首先我们模拟一个需求,大多说软件在使用时都会弹出 ...

  7. VSTO学习(五)——创建Word解决方案

    一.引言 在上一个专题中主要为大家介绍如何自定义我们的Excel 界面的,然而在这个专题中,我将为大家介绍如何用VSTO来创建Word项目,对于Word的VSTO开发和Excel的开发很类似,你同样也 ...

  8. 我的VSTO之路(五):Outlook初步开发之联系人扩展

    原文:我的VSTO之路(五):Outlook初步开发之联系人扩展 上一讲我们完成对Word的介绍,文本开始,我将着重介绍Outlook.Outlook是微软Office中一个非常实用的工具,尤其在一个 ...

  9. WCF开发实战系列五:创建WCF客户端程序

    WCF开发实战系列五:创建WCF客户端程序 (原创:灰灰虫的家http://hi.baidu.com/grayworm) 在前面的三篇文章中我们分别介绍了WCF服务的三种载体:IIS.Self-Hos ...

随机推荐

  1. DOM querySelector选择器

    原生的强大DOM选择器querySelector 在传统的 JavaScript 开发中,查找 DOM 往往是开发人员遇到的第一个头疼的问题,原生的 JavaScript 所提供的 DOM 选择方法并 ...

  2. 【Demo 0009】Android 组件(BroadcastReceiver)

    本章学习要点:        1.  了解Broadcast的作用;        2.  掌握自定义广播和系统广播的接收:        3.  掌握广播的发送:

  3. android——写xml

    在PersonService的基础上,加上savePersons(·····),这时的PersonService为: package com.njupt.xml; import java.io.Fil ...

  4. Andorid Binder进程间通信---总结

    一.Server和Service Manager进程间通信 Service Manager进程启动时,已经创建了Service Manager实体对象,没有Service Manager本地对象. S ...

  5. 基于android的实时音频频谱仪

    前一段实习,本来打算做c++,到了公司发现没啥项目,于是乎转行做了android,写的第一个程序竟然要我处理信号,咱可是一心搞计算机的,没接触过信号的东西,什么都没接触过,于是乎, 找各种朋友,各种熟 ...

  6. EasyUI - Tabs

    代码: 判断是不是已经存在,如果存在,则直接选中,否则创建新的tab. $('#tabs').tabs({ fit: true, border: false }) $('#Tree').tree({ ...

  7. QNX系统-关于delay函数与sleep函数的区别

    QNX是类unix系统.在c语言编程过程中,往往会用到delay或者sleep延时函数.两者之间在使用上有一定的区别!!! delay()是循环等待,该进程还在运行,占用处理器. sleep()不同, ...

  8. [置顶] Objective-C ,ios,iphone开发基础:命名规范

    命名规范:http://bukkake.iteye.com/blog/695492  点击打开链接

  9. tbb 线程安全concurrent_queue的性能

    tbb实现了线程安全的queue,这样程序员既可以不用和那些lock,mutex,criticalsection打交道,又大大提高性能,太给力了..比较的结果见代码中的注释.结果可以看出代码足足少一半 ...

  10. 键盘游戏之canvas--用OO方式写

    虽然写的不是很好,但 解释权以及版权仍然归13东倍所有!  <!DOCTYPE HTML> <html> <head> <title>canvas-00 ...