实现外接程序的 UI
我们的第一份业务定单是为我们的外接程序的功能生成用户界面。假如外接程序的 UI 要插入宿主应用程序中,我们将为 Connect 类类型定义一个类型为 Microsoft.Office.Core.CommandBarButton 的新成员变量:
public class Connect : Object, Extensibility.IDTExtensibility2 { ... // Our UI will consist of a single CommandBarButton private CommandBarButton btnGetEMailStats; } |
CommandBarButton 小部件(用于显示标题"Statistics")将插入到 Outlook 的标准命令栏中(图 10):
图 10. 自定义的 Statistics CommandBarButton
前面已经提到,假如宿主完全启动,则 OnStartupComplete() 方法是生成 UI 元素的理想位置。下面是将新的 CommandBarButton 类型插入到现有命令栏时所需的步骤:
*从活动的资源管理器获得命令栏集。
*查看按钮当前是否在希望修改的命令栏的控件集合中。如果不在,则创建并启用新的实例。
*在 CommandBarButton 中挂钩 Click 事件,以响应小部件的自定义功能。
这样,下面是经过更新的(并有详细批注) OnStartupComplete() 的实现:
public void OnStartupComplete(ref System.Array custom) { // First, get access to the CommandBars on // the active explorer. CommandBars commandBars = applicationObject.ActiveExplorer().CommandBars; try { // If our button is already // on the Standard CommandBar, use it. btnGetEMailStats = (CommandBarButton) commandBars["Standard"].Controls["Statistics"]; } catch { // OOPS! Our button is not there, so // we need to make a new instance. // Note that the Add() method was // defined to take optional parameters, // which are not supported in C#. // Thus we must specify Missing.Value. btnGetEMailStats = (CommandBarButton) commandBars["Standard"].Controls.Add(1, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value); btnGetEMailStats.Caption = "Statistics"; btnGetEMailStats.Style = MsoButtonStyle.msoButtonCaption; } // Setting the Tag property is not required, but can be used // to quickly reterive your button. btnGetEMailStats.Tag = "Statistics"; // Setting OnAction is also optional, however if you specify // the ProgID of the Add-in, the host will automatically // load the Add-in if the user clicks on the CommandBarButton when // the Add-in is not loaded. After this point, the Click // event handler is called. btnGetEMailStats.OnAction = "!"; btnGetEMailStats.Visible = true; // Rig-up the Click event for the new CommandBarButton type. btnGetEMailStats.Click += new _CommandBarButtonEvents_ClickEventHandler( btnGetEMailStats_Click); } |
注意,CommandBarButton 已被配置为在被单击时调用名为 btnGetEMailStats_Click() 的方法。我们可以很快实现自定义逻辑,但目前只是下面的 stub 代码:
private void btnGetEMailStats_Click(CommandBarButton Ctrl, ref bool CancelDefault) { // ToDo: Implement custom logic. } |
删除 UI
现在,我们完成了一旦宿主启动就创建 CommandBarButton 的逻辑,然后我们将修改 OnBeginShutdown() 以便在关闭时删除这个小部件:
public void OnBeginShutdown(ref System.Array custom) { // Get set of command bars on active explorer. CommandBars commandBars = applicationObject.ActiveExplorer().CommandBars; try { // Find our button and kill it. commandBars["Standard"].Controls["GetEMailStats"].Delete( System.Reflection.Missing.Value); } catch(System.Exception ex) {MessageBox.Show(ex.Message);} } |
注 您可能猜到,可以用很多方式扩展 Outlook 2003 的 GUI.要了解其他技术,请参阅 Creating Managed Outlook Buttons with Icons.实现电子邮件统计逻辑
最后的任务是在 Click 事件处理程序中实现逻辑。我们将利用 Outlook 对象模型来确定每天和每月所接收和发送的电子邮件数。在生成 OPine 以后,以下逻辑应当相当简单:
private void btnGetEMailStats_Click(CommandBarButton Ctrl, ref bool CancelDefault) { string statInfo; DateTime today = DateTime.Today; // The stats we are tracing. int eMailsToday = 0; int eMailsThisMonth = 0; int eMailSentToday = 0; int eMailSentThisMonth = 0; // Get items in user's inbox. NameSpace outlookNS = applicationObject.GetNamespace("MAPI"); MAPIFolder inboxFolder = outlookNS.GetDefaultFolder(OlDefaultFolders.olFolderInbox); // Compare time received to current day / month // and update our counters. foreach(object item in inboxFolder.Items) { MailItem mi = item as MailItem; if(mi != null) { if(mi.ReceivedTime.Day == today.Day) eMailsToday++; if(mi.ReceivedTime.Month == today.Month) eMailsThisMonth++; } } // Build first part of statInfo string. statInfo = string.Format("E-mails received today: {0}\n", eMailsToday); statInfo += string.Format("E-mails received this Month: {0}\n", eMailsThisMonth); statInfo += "--------------------------------------\n"; // Get items in user's sent item folder and // test again. MAPIFolder SentFolder = outlookNS.GetDefaultFolder(OlDefaultFolders.olFolderSentMail); foreach(object item in SentFolder.Items) { // See if current item is a MailItem MailItem mi = item as MailItem; if(mi != null) { // It is, so get day/month stats. if(mi.SentOn.Day == today.Day) eMailSentToday++; if(mi.SentOn.Month == today.Month) eMailSentThisMonth++; } } // Build last part of statInfo string. statInfo += string.Format("E-mails sent today: {0}\n", eMailSentToday); statInfo += string.Format("E-mails sent this Month: {0}\n", eMailSentThisMonth); // Show results. MessageBox.Show(statInfo, "Current E-mail stats"); }
|
到这里,我们的外接程序就完成了!假定您能够编译项目而没有错误,那么现在就可以注册和测试 EMailStatsAddIn 功能了。
注册共享外接程序
请回忆,在用 Visual Studio.NET 2003 创建共享外接程序项目时,您收到过一个安装项目。要生成可以使用的 EMailStatsAddIn,请在解决方案资源管理器中右键单击 EMailStatsAddInSetup 项目图标,并选择"Rebuild"(图 11)。
图 11. 生成安装程序
在此以后,项目目录将包含标准的安装可执行文件和 *msi 安装程序文件。可以使用这些文件安装外接程序,也可以直接在 Visual Studio.NET 2003 中进行安装(图 12)。
图 12. 通过 VisualStudio.NET 2003 安装 EMailStatsAddIn
现在,当启动 Outlook 2003 时,应当在标准命令栏中找到 Statistics 按钮。毫无疑问,单击它时,将看到今天的电子邮件统计信息(图 13)。
图 13. 运行中的 EMailStatsAddIn
注 值得说明的是,为了满足您的需要,可能需要对 Visual Studio.NET 2003 生成的安装逻辑加以修改。您的 .NET 程序集可能无法将自己正确注册为可被 COM 使用。如果出现这样的情况,托管的外接程序就无法出现在 Outlook COM 外接程序对话框中,如果没有将外接程序配置为在启动时启动,这会是很大的问题。Microsoft 的 Omar Shahine 已在 http://go.microsoft.com/fwlink/?LinkId=30833 张贴了这个问题的解决方案。另一个关于该问题的观点可以在 http://blogs.msdn.com/robmen/archive/2004/04/28/122491.aspx 找到。
小结
我们已经看到,使用主互操作程序集,。NET 开发人员可以与 Outlook 2003 类型交互。Application 类型是该模型的根,而该模型公开了代表各种 Outlook 项的很多集合。在开发命令行驱动的邮件应用程序 (OPine) 期间,您已经了解如何通过编程创建并获得各个项,以及如何响应选择事件。我们已经阐明,通过创建自定义外接程序,可以对 Outlook 2003 本身进行扩展。Visual Studio.NET 2003 为此提供了具体的项目模板,该模板可以产生实现 IDTExtensibility2 接口的类,以及相关的安装程序项目。
查看本文来源