如何使用.NET开发全版本支持的Outlook插件产品(四)——进阶探讨
插件项目所有代码都已经上传至
https://github.com/VanPan/TestOutlookAdding
如何定制Ribbon在不同界面的显示
实际使用过程中出现的问题
这个问题的来自十分实际的几个事件,首先请大家回忆现在的插件入口类的声明特性,以及插件Ribbon界面XML的定义。
[COMAddin("Test Addin For Outlook", "", 3), CustomUI("TestOutlookAddin.RibbonUI.xml"), RegistryLocation(RegistrySaveLocation.CurrentUser)]
[Guid("AFE67651-951D-4A42-8CAB-E9BF7E219DDF"), ProgId("TestAddinForOutlook")]
public class COMEntry : COMAddin
请特别注意其中的
CustomUI("TestOutlookAddin.RibbonUI.xml")
而这个XML文件,大家已经再熟悉不过
<?xml version="1.0" encoding="utf-8" ?>
<customUI onLoad="LoadAction" xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
<ribbon>
<tabs>
<tab id="RibbonAddinSampleTabCS35" label="插件标签">
<group id="group1" label="分组名">
<button id="customButton1" size="large" onAction="ButtonAction" getLabel="GetButtonLabel" getImage="GetButtonImage"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
当大家运行现在的插件,会发现,新增的Robbin标签会出现在所有Outlook打开的界面中,例如:
Outlook启动界面
新建邮件界面
如果按照现在的代码,所有的Outlook界面都会出现插件的标签。现在,在实际更深层次的使用过程中,我们面临两个问题:
1.如果我只想在主界面或者新建邮件等特定界面,加载插件标签,应该怎么办?
2.如果我想把插件嵌入到系统Ribbon的Tab中,应该怎么办?
在特定的界面加载特定的Ribbon
首先回答问题1
解决动态加载Ribbon的关键,在于重写COMAddin类中的GetCustomUI方法,如下:
public override string GetCustomUI(string RibbonID)
{
if (RibbonID != "Microsoft.Outlook.Explorer") return "";
var ui = base.GetCustomUI(RibbonID);
return ui;
}
这个方法在每次打开新界面时都会调用。这样定义以后,通过判断RibbonID来区分当前打开的界面的ID来返回相应的XML内容,即可满足我们的要求。
返回的结果字符串是XML文档的内容,而不是XML文件夹哦,这点需要注意。在上面的代码中,返回的就是项目默认XML文档TestOutlookAddin.RibbonUI.xml中的内容,因为是用的基类方法。
大家可以在调试状态下,通过打开不同的界面来验证每个界面的RibbonID是什么,在此不再赘述。
在系统级别Ribbon中注入新控件
现在再讨论第二个问题,如果有需求,在系统“邮件”标签中加入自定义的按钮,应该怎么办?
方法是在XML文件中加入新的声明,关键是使用idMso元素来指定系统级Tab,我们将XML文件改成如下:
<?xml version="1.0" encoding="utf-8" ?>
<customUI onLoad="LoadAction" xmlns="http://schemas.microsoft.com/office/2006/01/customui" >
<ribbon>
<tabs>
<tab idMso="TabView">
<group id="group2" label="新分组">
<button id="customButton2" size="large" onAction="ButtonAction" getLabel="GetButtonLabel" getImage="GetButtonImage"/>
</group>
</tab>
<tab id="RibbonAddinSampleTabCS35" label="插件标签">
<group id="group1" label="分组名">
<button id="customButton1" size="large" onAction="ButtonAction" getLabel="GetButtonLabel" getImage="GetButtonImage"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
可以看到,在原来id是RibbonAddinSampleTabCS35的tab项上面,我们定义了新的tab,idMso是TabView。
这个声明,指定了采用Outlook中的“视图”标签,我们看到运行后的效果如下:
这样,在“视图”标签的最后,我们就增加了一个新的分组和按钮。
附上查看所有Office Ribbon ID的方法
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=6627
通过结合上面两个方法,我们就可以对系统的菜单项进行动态全面控制了,对于Ribbon的自定义也方便了许多。
如何增加邮件签名
下面我们讨论另外一个在开发中也会遇到的问题:如何读取和控制邮件内容。
在此列举一个最实际的场景:当邮件打开时,我们想要动态分析邮件内容,并进行后续操作。当邮件发送时,我们希望可以动态添加一些文字来作为签名或者其它推广类信息。
如果需要实现这个功能,方案如下:
首先,在OnConnection事件的处理方法中,加入以下代码:
// register add signature after new mail
var i = _outlookApplication.Inspectors as OutLook.Inspectors;
if (i != null)
{
i.NewInspectorEvent += i_NewInspectorEvent;
}
这段代码的主要目的是为新建一个项目(邮件、联系人、会议等)注册一个事件。
随后我们在事件处理函数中这样写:
private OutLook.MailItem _newMail; void i_NewInspectorEvent(OutLook._Inspector Inspector)
{
_newMail = Inspector.CurrentItem as OutLook.MailItem;
if (_newMail == null || !String.IsNullOrEmpty(_newMail.EntryID)) return;
_newMail.SendEvent += newMail_SendEvent;
}
这段代码的意义,在于判断打开的是新建邮件的重口,这样我们就可以获得当前正在新建的邮件实例对象了。
同时我们对邮件的发送事件再次注入事件
void newMail_SendEvent(ref bool Cancel)
{
_newMail.HTMLBody = _newMail.HTMLBody.Replace("</body>", "<p class=MsoNormal><span lang=EN-US><a href=\"http://www.camcard.com\">Click Me</a></span></p></body>");
}
以上这段代码的作用是在邮件发送时自动在后面加入签名超链接。但是还是有些地方值得稍微解释一下:
首先,邮件主流分为三种格式:普通文本、HTML、RTF。默认的邮件格式可以在Outlook 2013的“文件”——“选项”——“邮件”中找到设置。
我们可以在MailItem.MailFormat属性中看到当前邮件的撰写格式,如果邮件是HTML格式的,我们需要设置MailItem.HTMLBody;如果邮件是RTF格式的,我们需要相应设置MailItem.RTFBody。
在现在的例子中,我们使用的是HTML格式,如果是HTML格式,我们可以理解这封邮件就是一个HTML页面,那拼接签名的方法最简单的莫过于将HTML中的</body>关闭标签替换成一段签名然后再重现关闭。
对于RTF格式,也是有其它格式可以进行编辑,但是我在这方面没有深入调研。
PS:如果你不知道HTML,请对HTML进行一定量的学习,因为现在Web开发也是非常主流的一块,作为程序员,应该对所有平台的开发都有一定的了解,HTML又是网页开发最基础的一块。
总结
到此,我们已经对插件的进一步开发又有了更多的了解,可以控制的范围也越来越深入,后面的开发教程,等待我收集更多的实际案例,并逐步在后续的分享中加入到博客中。
后续我们将正式介绍安装包的制作,WIX安装包不是仅仅用在插件安装,也可以用于基于.NET的所有PC平台的安装项目中。
如何使用.NET开发全版本支持的Outlook插件产品(四)——进阶探讨的更多相关文章
- 如何使用.NET开发全版本支持的Outlook插件产品(三)——全面控制
插件项目所有代码都已经上传至 https://github.com/VanPan/TestOutlookAdding 进阶基础--COM查看 首先,对于Outlook对象模型,MSDN早就有非常详细的 ...
- 如何使用.NET开发全版本支持的Outlook插件产品(一)——准备工作
这半年一直在做Outlook的插件,因为不会VC++,所以想找一款基于.NET,用C#开发Outlook插件的技术方案.没想到,光技术选型这件事,就用各种技术手段验证了将近一个月,还花费了大量的精力做 ...
- 如何使用.NET开发全版本支持的Outlook插件产品(二)——完善插件
插件项目所有代码都已经上传至 https://github.com/VanPan/TestOutlookAdding 勿在浮砂筑高台--定位错误 在介绍后面的插件开发技术之前,让我们先来看看已经达到的 ...
- mac 下基于firebreath 开发多浏览器支持的浏览器插件
mac 下基于firebreath 开发多浏览器支持的浏览器插件 首先要区分什么是浏览器扩展和浏览器插件;插件可以像本地程序一样做的更多 一. 关于 firebreath http://www.fir ...
- iOS:iOS开发非常全的三方库、插件等等
iOS开发非常全的三方库.插件等等 github排名:https://github.com/trending, github搜索:https://github.com/search. 此文章转自git ...
- 偏执的iOS逆向研究员:收集全版本的macOS iOS+越狱+内核调试
Intro 虽然“只有偏执狂才能够生存”这句话已经被假药停给毁了,但是作为一只有逼格的高大上的iOS逆向分析研究员,难道如果有现成的macOS/iOS全版本镜像可以下载并且无限“漫游”,难道你就不想来 ...
- 新成员!Visual Studio Code --跨平台的开发工具(支持OSX, Linux 和 Windows)
原文出处:新成员!Visual Studio Code --跨平台的开发工具(支持OSX, Linux 和 Windows) 这是我的文章备份 http://www.dotblogs.com.tw/ ...
- [EXP]IIS全版本提权工具
工具: iislpe.exe 编译: .net 3.5 全版本IIS提权工具,支持IIS应用池用户/网络服务用户/本地服务用户 原理: 通过NTLM重放将权限提升至SYSTEM权限,详情参 ...
- Windows全版本KMS激活脚本
搭建了个KMS服务器,制作了个批处理激活脚本,所有代码可以看到,让你再也不用担心系统会被有些激活工具强改主页,留有后门的风险了. 本脚本可以激活Windows全版本,安全.绿色. 1.首先你的系统必须 ...
随机推荐
- gulp与webpack-stream集成配置
webpack非常强大,但是也有不足的地方,批量式处理依然是gulp更胜一筹.我们是否可以将两者的优点结合起来呢? 这篇文章就是讲述如何集成gulp和webpack 1.安装webpack-strea ...
- static修饰的静态内部类
Java里面static一般用来修饰成员变量或函数.但有一种特殊用法是用static修饰内部类,普通类是不允许声明为静态的,只有内部类才可以.被static修饰的内部类可以直接作为一个普通类来使用,而 ...
- python迭代器
首先解释以下迭代器跟可迭代对象(Iterable)的区别,可以直接作用于for循环或者实现了__iter__的对象统称为可迭代对象(Iterable).可以被next()函数调用并不断返回下一个值的对 ...
- mac 安装php7
卸载php55 brew unlink php55 brew install homebrew/php/php70 安装成功信息 To enable PHP in Apache add the fol ...
- FullPage.js – 轻松实现全屏滚动(单页网站)效果
FullPage.js 是一个简单而易于使用的插件,用来创建全屏滚动网站(也被称为单页网站).除了可以创建全屏滚动效果以外,也可以给网站添加一些水平的滑块效果.能够自适应不同的屏幕尺寸,包括平板电脑和 ...
- tsql语句分析工具 转
一款好用且免费的语句分析工具 在调优过程中的查询语句优化阶段,分析语句的执行计划是必经之路,一款好的执行计划分析工具确实可以帮助我们事半功倍 一款名为“Plan Explorer“,自己用的挺爽,不私 ...
- 数字图像处理作业使用OpenCV - 自定义直方图
第二次作业需要打印出来灰度直方图,当然不能使用ocv的自带calcHist函数来得到Mat对象了……结果上网搜索怎么用自己的数据创建直方图,搜到的都是直接用函数的_(:з」∠)_ 结果这个地方拖了好久 ...
- 当执行太多不受信任的代码时,除去令人讨厌的大量 trycatch 的办法
如果方法 Condition 返回 true,则执行 IfTrue,否则执行 IfFalse,发生异常则执行 IfError. 通常是这样: try { if (Condition()) { try ...
- Extjs 源码组成(4.0.7)
(function(){})()形式的自执行,构建Ext对象(0~584) 1 设置全局对象EXt:global.Ext = {}, 2 实现了Ext对象面向对象编程的基础方法,如,apply,ex ...
- 通过图片对比带给你不一样的KMP算法体验
KMP 算法,俗称“看毛片”算法,是字符串匹配中的很强大的一个算法,不过,对于初学者来说,要弄懂它确实不易. 笔者认为,KMP 算法之所以难懂,很大一部分原因是很多实现的方法在一些细节的差异.体现在几 ...