插件項目所有代碼都已經上傳至
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平台的安裝項目中。