久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

RibbonX API: 利用您自己的功能區(qū)選項(xiàng)卡和控件擴(kuò)展 2007 Office Sy...

 qrzhcd 2012-04-17
利用您自己的功能區(qū)選項(xiàng)卡和控件擴(kuò)展 2007 Office System
Eric Faller

本文討論:
  • 功能區(qū)簡介
  • RibbonX 控件和功能
  • 升級加載項(xiàng)以使用 RibbonX
  • 為 Word 和 Excel 構(gòu)建加載項(xiàng)
本文使用了以下技術(shù):
2007 Microsoft Office 系統(tǒng)
下載本文中所用的代碼: RibbonX2007_02.exe (201 KB)
瀏覽在線代碼
如果您曾見過 2007 Microsoft Office 系統(tǒng),,那么您會發(fā)現(xiàn)新的 Microsoft? Office 用戶界面與以前的 Office 版本有著本質(zhì)的區(qū)別,。因此,當(dāng)您了解到 UI 背后的可擴(kuò)展性模型也為全新時(shí),,應(yīng)該也不會感到吃驚了,。
與其擴(kuò)展的舊工具欄和菜單非常類似,CommandBars 對象模型(從 Office 97 開始提供)難以有效地使用,。新模型被稱為 RibbonX,,它具有許多與新 UI 本身相同的屬性:易于使用、一致性,、時(shí)尚性和可預(yù)見性(對最終用戶而言),。
通過使用 XML 來指定 UI 的內(nèi)容和結(jié)構(gòu)并在其背后使用動態(tài)回調(diào)機(jī)制,RibbonX 將 UI 設(shè)計(jì)從其背后的代碼中解脫出來,。稍后我將在本文中說明所有相關(guān)細(xì)節(jié),,但在這之前,我會先介紹經(jīng)驗(yàn)豐富的 Office 開發(fā)人員可能感興趣的一些有關(guān)新 UI 的內(nèi)容。
在拋棄舊 UI 的同時(shí),,Microsoft 也舍棄了許多熟悉的術(shù)語并使用陌生的新概念來代替它們,。我們先來看看新 UI 的基礎(chǔ)知識,確保所有人都能對它有基本了解,。圖 1 顯示的 Microsoft Office Word 2007 上標(biāo)出了每個(gè)主要 UI 組件,。
圖 1 新 Word 2007 界面的元素 (單擊該圖像獲得較大視圖)
1. 功能區(qū) 文檔上方的大矩形區(qū)域即是功能區(qū)。它包含標(biāo)題欄,、Office 按鈕,、快速訪問工具欄及選項(xiàng)卡。RibbonX 主要應(yīng)用于功能區(qū)及其內(nèi)部的每一項(xiàng),。
2. Office 按鈕 此按鈕會顯示 Office 菜單,,該菜單與 Office 先前版本中的“文件”菜單大致相同。Office 菜單包含多個(gè)命令,,這些命令是對文檔進(jìn)行操作,,而不是對文檔的內(nèi)容進(jìn)行操作。使用 RibbonX 加載項(xiàng)可以隨意改變 Office 菜單的內(nèi)容(但是它們不能自定義 Office 按鈕本身),。
3. 快速訪問工具欄 此工具欄包含常用的命令,,而且是最終用戶進(jìn)行自定義的主要位置。用戶可以右鍵單擊任何功能區(qū)控件并將其添加到快速訪問工具欄(包括自定義 RibbonX 控件),。因?yàn)樗脑O(shè)計(jì)目的便是作為一塊“屬于”最終用戶的空間,,所以通常不允許 RibbonX 加載項(xiàng)改變快速訪問工具欄,除非它們已經(jīng)啟用 StartFromScratch 模式,。
4. 選項(xiàng)卡 選項(xiàng)卡是構(gòu)成功能區(qū)的主要內(nèi)容,,而且包含用于處理文檔內(nèi)容的 UI 控件。RibbonX 加載項(xiàng)可以創(chuàng)建它們自己的自定義選項(xiàng)卡,,并改變內(nèi)置選項(xiàng)卡的可見性和標(biāo)簽,。
5. 上下文選項(xiàng)卡集 選中文檔內(nèi)部的對象(例如圖片或表)時(shí),即會出現(xiàn)上下文選項(xiàng)卡集,,其中包含所有用于處理這些對象的 UI 元素,。RibbonX 加載項(xiàng)可以改變內(nèi)置選項(xiàng)卡集的可見性,并向其添加自定義選項(xiàng)卡,。2007 Office 版本不支持創(chuàng)建自定義上下文選項(xiàng)卡集,。選項(xiàng)卡集包含上下文選項(xiàng)卡,它們的作用方式與常規(guī)選項(xiàng)卡相同,。
6. 組 選項(xiàng)卡包含組的集合,,組中則包含各個(gè) UI 控件。RibbonX 加載項(xiàng)可以改變內(nèi)置組的可見性,,并創(chuàng)建它們自己的自定義組,。但它們不能改變內(nèi)置組的內(nèi)容,。此限制可以保護(hù) UI 布局并防止加載項(xiàng)之間相互沖突以及加載項(xiàng)與 Office 的將來版本發(fā)生沖突。根據(jù)選擇,,組的角落處可擁有對話框啟動器,,用于顯示與組相關(guān)的對話框(例如“字體”或“段落”對話框)。
7. 任務(wù)窗格 2007 Office 系統(tǒng)中仍存在若干任務(wù)窗格,,而且現(xiàn)在支持同時(shí)打開多個(gè)任務(wù)窗格,。COM 加載項(xiàng)現(xiàn)在可以創(chuàng)建托管 ActiveX? 控件或 Windows? 窗體控件等內(nèi)容的 CustomTaskPane。(CustomTaskPane 功能與 RibbonX 不同,,但本文不會對此進(jìn)行介紹,。)
8. MiniToolbar MiniToolbar 是選定文本和右鍵單擊上下文菜單時(shí)出現(xiàn)的常見格式命令集合。RibbonX 加載項(xiàng)不能修改 MiniToolbar 的內(nèi)容,,但它們可以禁用或重用其內(nèi)置命令,。
9. 上下文菜單 這些上下文菜單與 Office 先前版本中我們熟悉和喜愛的那些上下文菜單相同。在 2007 Office 版本中,,RibbonX 不應(yīng)用于上下文菜單,,但使用 CommandBars 對象模型可以像過去那樣擴(kuò)展和自定義它們。
10. 狀態(tài)欄 狀態(tài)欄包含幾個(gè)方便的新控件,,如字?jǐn)?shù)統(tǒng)計(jì)和視圖滑塊,。盡管狀態(tài)欄可以隱藏,但在 2007 Office 系統(tǒng)中加載項(xiàng)不可以自定義狀態(tài)欄,。

對現(xiàn)有加載項(xiàng)的支持
如果您已針對 Office 2003 編寫了加載項(xiàng),您可能想知道它們在 2007 版本中是否仍起作用,。很高興,,答案是肯定的,它們?nèi)钥梢院芎玫剡\(yùn)行(除非它們做些不可思議的事情,,如檢查 Office 版本并拒絕在新版本上運(yùn)行),。所有的舊菜單和工具欄仍存在于表面之下,原因很簡單,,因?yàn)椴倏厮鼈兊呐f式加載項(xiàng)仍需要在 2007 Office 系統(tǒng)上運(yùn)行,。它們在新 UI 中如何顯示?讓我們看一個(gè)示例,。
圖 2 顯示了一個(gè)假定的 Word 2003 加載項(xiàng)(該加載項(xiàng)創(chuàng)建一個(gè)自定義工具欄并將幾個(gè)按鈕添加到舊菜單和工具欄)以及在 Word 2007 中進(jìn)行加載時(shí)該加載項(xiàng)的外觀,。
圖 2a Word 2003 和 Word 2007 中的同一加載項(xiàng) 
圖 2b
如您所見,當(dāng)加載舊式 CommandBar 加載項(xiàng)時(shí),,“加載項(xiàng)”選項(xiàng)卡顯示在功能區(qū)內(nèi),。“加載項(xiàng)”選項(xiàng)卡包含三個(gè)組:“菜單命令”,、“工具欄命令”和“自定義工具欄”,?!安藛蚊睢焙汀肮ぞ邫诿睢苯M分別包含添加到舊式內(nèi)置菜單和工具欄中的自定義控件。它們還顯示由加載項(xiàng)重用以執(zhí)行自定義操作(通過設(shè)置 OnAction 或 Hyperlink 屬性)的任何舊式內(nèi)置控件,?!白远x工具欄”組將任何舊式自定義工具欄顯示為水平區(qū)域??丶墓ぞ咛崾緯@示控件所在的舊式工具欄的名稱,。
如果在卸載后某個(gè)行為異常的加載項(xiàng)留在了按鈕背后,用戶可以右鍵單擊“加載項(xiàng)”選項(xiàng)卡中的控件,,然后將它們從舊式 CommandBar 結(jié)構(gòu)中刪除,。

RibbonX 中的新功能
RibbonX 使 Office 編程進(jìn)入基于 XML 的 UI 聲明的現(xiàn)代化時(shí)代。您現(xiàn)在可以在結(jié)構(gòu)化標(biāo)記窗體中創(chuàng)建指定 UI 外觀的 XML 文件,,而不再需要使用一系列對象模型調(diào)用來編寫構(gòu)建 UI 的復(fù)雜代碼,。這對于加載項(xiàng)編寫者而言有許多好處。
首先,,您可以將 UI 與代碼分離,。UI 設(shè)計(jì)者不需要為了嘗試新設(shè)計(jì)而知道手動更新代碼的方法。事實(shí)上,,如果加載項(xiàng)選擇從外部文件加載其 XML,,那么甚至可以不必重新編譯該加載項(xiàng)即可修改和完善 UI。這便消除了硬編碼 UI 系統(tǒng)所需的反復(fù)“編輯”,、“編譯”,、“運(yùn)行”循環(huán)的中間步驟。
其次,,Office 能分辨加載項(xiàng)的完整 UI,。這一點(diǎn)看上去似乎并不重要。但是,,如果您知道使用 CommandBars 時(shí),,Office 的先前版本不知道哪些工具欄和菜單屬于哪個(gè)加載項(xiàng),而且所有的 UI 修改都通過 COM 調(diào)用來實(shí)現(xiàn),,而這些調(diào)用不可追溯回到任何個(gè)別加載項(xiàng),,那么您就能明白它的重要性。Office 之前版本的這個(gè)特點(diǎn)會導(dǎo)致一些煩人的問題,,而現(xiàn)在這些問題完全可以避免,。
第三,Office 可以自動清理加載項(xiàng)的 UI,。以前,,加載項(xiàng)必須使用特殊代碼在關(guān)閉或卸載時(shí)檢查其菜單和工具欄并將它們刪除。如果加載項(xiàng)崩潰或不能正確地進(jìn)行自身清理(此情況曾多次發(fā)生),,它會將無用的按鈕留在 UI 中,。由于 2007 Office 系統(tǒng)可以自動清理加載項(xiàng) UI,,因此不必寫入任何清理代碼,也不會有殘留的 UI,。
不同 Office 版本之間的差別是您需避免的另一個(gè)問題,。有效的 XML 文件需要包含 xmlns 命名空間聲明,用于標(biāo)識文件所遵循的架構(gòu)版本,。這樣,,RibbonX 便能得知特定加載項(xiàng)所針對的 Office 版本,并能在版本之間有差異時(shí)正確映射 UI,。CommandBars 對象模型缺少版本控制和所有權(quán)是造成以下情況的兩個(gè)主要原因:更新到新版本 Office 時(shí)舊式加載項(xiàng)常常遭到破壞,;“加載項(xiàng)”選項(xiàng)卡無法很好地區(qū)分由 OM 調(diào)用添加到其中的雜亂控件。
最后,,XML 具有良好的工具支持,。只需通過拖放,便能利用所提供的 RibbonX 架構(gòu)定義文件 (XSD),、各種 XML 編輯器(包括 Word 2007 本身)創(chuàng)建有效的 RibbonX UI 文件,。
CommandBars 對象模型可視為使用“推”模型,其中加載項(xiàng)會通過設(shè)置對象模型中的各種屬性將所有 UI 數(shù)據(jù)推入 Office,。UI 中控件的每個(gè)屬性必須在啟動時(shí)由加載項(xiàng)明確設(shè)置,,即使此控件所在的菜單或工具欄從未顯示。如果這涉及加載大量圖像文件,,則會對性能造成極大影響,。
RibbonX 使用“拉”模型,其中 Office 僅在需要時(shí)將數(shù)據(jù)從加載項(xiàng)中拉出,。加載項(xiàng)提供 get 回調(diào),,例如 getLabel 或 getImage,而不再設(shè)置像 CommandBar.Name 或 CommandBarButton.Picture 之類的屬性,。需要知道某個(gè)控件的標(biāo)簽或圖像時(shí),,Office 便會調(diào)用這些回調(diào),。
拉模型的主要優(yōu)點(diǎn)在于性能優(yōu)勢,。在 2007 Office 版本中,應(yīng)用程序啟動時(shí)可能大多數(shù)加載項(xiàng)的 UI 都不可見,,尤其是當(dāng)加載項(xiàng)在“加載項(xiàng)”選項(xiàng)卡中添加了自己的頂級選項(xiàng)卡或組時(shí),。因此沒有必要立即加載這些控件的所有圖像,否則會導(dǎo)致性能急劇下降,。僅需在用戶單擊該選項(xiàng)卡時(shí)加載圖像,。RibbonX 會盡可能延遲回調(diào)的調(diào)用,以分?jǐn)傉麄€(gè)會話中的資源加載成本,,并在即便安裝了若干加載項(xiàng)的情況下保持 Office 應(yīng)用程序快速啟動,。
如果 Office 確定調(diào)用這些回調(diào)的時(shí)間,,您可能想知道如何動態(tài)更改控件屬性。RibbonX 緩存回調(diào)的返回值,,并且在加載項(xiàng)使這些返回值無效之前不會進(jìn)行回調(diào),。加載項(xiàng)可以通過 IRibbonUI 接口的 Invalidate 和 InvalidateControl 方法來實(shí)現(xiàn)此目的。一旦控件的屬性失效,,RibbonX 即會知道在下次需要時(shí)進(jìn)行回調(diào),。如果此控件當(dāng)前顯示在屏幕上,它將立即回調(diào)并更新值,。如果它沒有顯示在屏幕上,,則 RibbonX 會等到它出現(xiàn)在屏幕上時(shí)才進(jìn)行回調(diào)。下面我們將深入探討實(shí)現(xiàn)回調(diào)功能的所有細(xì)節(jié),,并在文中的示例加載項(xiàng)中詳細(xì)介紹如何進(jìn)行失效,。
RibbonX 提供許多不同的控件類型以用于擴(kuò)展,包括圖 3 中所示的這些控件類型,。CommandBars 只能使用此列表中的前六項(xiàng),,但現(xiàn)在有許多新 UI 選項(xiàng)可供 RibbonX 加載項(xiàng)使用。其中,,最引人注目的新控件類型應(yīng)是包括按鈕和下拉菜單的 splitButton(請參見圖 4)以及展開以顯示圖像選擇的庫,。兩者均廣泛應(yīng)用于 2007 Office 版本中,目的是減少 UI 混亂并方便預(yù)覽可見操作,。我們也鼓勵(lì)加載項(xiàng)編寫者使用這些新控件類型來為自己的 UI 提供相同的效果,。

RibbonX 控件
1. 按鈕
2. toggleButton
3. editBox
4. 菜單
5. comboBox
6. dropDown
7. dialogBoxLauncher
8. 庫
9. splitButton
10. 標(biāo)簽
11. checkBox
12. 組
13. 選項(xiàng)卡
14. superTip
圖 4 SplitButton 

StartFromScratch 模式
許多開發(fā)人員使用 Office 作為平臺來構(gòu)建自己的自我包含應(yīng)用程序。運(yùn)行時(shí),,這些應(yīng)用程序通常會刪除所有的內(nèi)置 Office UI 并使用自己的 UI 進(jìn)行替換,。因?yàn)椴淮嬖谑褂?CommandBars 執(zhí)行此操作的標(biāo)準(zhǔn)機(jī)制,因此實(shí)施過程中總是充滿了困難和錯(cuò)誤,。
RibbonX 引入了 StartFromScratch 模式,,從而使隱藏 Office UI 與編寫一行 XML 一樣容易。在啟動 <ribbon> 標(biāo)記上設(shè)置 startFromScratch="true",,將執(zhí)行以下操作:
  • 隱藏所有的主要頂級內(nèi)置選項(xiàng)卡(但不包括上下文選項(xiàng)卡集)
  • 隱藏快速訪問工具欄的內(nèi)容
  • 允許加載項(xiàng)將自己的按鈕添加到快速訪問工具欄(這通常是受到禁止的)
  • 隱藏 Office 菜單上除“新建”,、“打開”和“保存”以外的所有命令
一旦應(yīng)用這些更改,加載項(xiàng)可以進(jìn)一步更改 UI,,包括顯示某些內(nèi)置選項(xiàng)卡或隱藏更多的選項(xiàng)卡集或 Office 菜單項(xiàng),。
通過手動隱藏所有這些 UI 元素可以執(zhí)行 StartFromScratch 模式的大多數(shù)功能,但與手動執(zhí)行此操作相比,,StartFromScratch 具有明顯優(yōu)勢,。首先,編寫一行 XML 代碼比寫五十行要容易多了,。其次,,它的設(shè)計(jì)向前兼容將來的 Office 版本,。如果 Word 的新版本添加了新的頂級選項(xiàng)卡或 Office 菜單項(xiàng),StartFromScratch 模式會自動隱藏它們,,但手動隱藏 UI 的加載項(xiàng)則需要更新才能隱藏這些新元素,。
StartFromScratch 模式的另一個(gè)重要功能是它基于每個(gè)文檔工作。如果用戶在多文檔界面 (MDI) 模式下編輯多個(gè)文檔,,文檔之一啟用了 StartFromScratch 模式,,那么用戶在該文檔與其他文檔之間切換時(shí),所有 UI 都將自動隱藏或顯示,。不需要任何代碼,!

命令禁用和重用
Office 加載項(xiàng)的另一個(gè)常見用途是禁用內(nèi)置命令。RibbonX 仍可使此操作與編寫一行代碼一樣容易,。開發(fā)人員可以使用與 XML 的 <commands> 部分中內(nèi)容類似的行來禁用內(nèi)置命令:
<command idMso="Bold" enabled="false"/> 
這將禁用在 UI 任何位置出現(xiàn)的“Bold”(粗體)按鈕(默認(rèn)配置下,,UI 的功能區(qū)及 MiniToolbar 都包括“Font”(字體)組)。
因?yàn)槭褂?CommandBars 不會發(fā)生此情況,,所以務(wù)必要注意此操作會禁用兩個(gè)位置中的“Bold”(粗體)按鈕,。當(dāng)用戶自定義了工具欄并將副本放置在其他位置時(shí),加載項(xiàng)需要從頭至尾檢查整個(gè) UI 并手動禁用該按鈕的每個(gè)副本,。它們還必須按其 ID 號(例如 43 或其他數(shù)字)來搜索命令,,而不是按用戶易理解的名稱(如“Bold”)進(jìn)行搜索。如果加載項(xiàng)想在某些時(shí)刻有條件地禁用命令,,則還可以使用 getEnabled 回調(diào),。
<commands> XML 元素也是 RibbonX 命令重用功能的始發(fā)區(qū)域。加載項(xiàng)通常會增強(qiáng)或擴(kuò)展 Office 的內(nèi)置功能,、接管現(xiàn)有的 UI 按鈕并重用它們,。另外,IT 管理員有時(shí)還選擇使用重用來限制功能(例如,,單擊“打印”按鈕時(shí)顯示密碼對話框),。
可以使用 RibbonX 來重用在單擊時(shí)執(zhí)行操作的任何按鈕(但不能重用較復(fù)雜的控件類型,例如庫或組合框),。下面是重用“Save”(保存)按鈕所需的 XML 的示例:
<command idMso="Save" onAction="MySaveFunction"/>
當(dāng)單擊“Save”(保存)時(shí),,加載項(xiàng)的 MySaveFunction 將運(yùn)行,從而為加載項(xiàng)提供執(zhí)行其自己的操作的機(jī)會,,并可選擇是否允許內(nèi)置 Save 函數(shù)執(zhí)行,。
再次,,Save 按鈕的所有副本(位于 Office 菜單和快速訪問工具欄上)將由此行 XML 重用,,并且如果個(gè)別文檔正在執(zhí)行重用,則此操作不會應(yīng)用于其他打開的文檔(除非該文檔被加載為全局模板或加載項(xiàng)),。

按需加載
使用 Office 加載項(xiàng)的一個(gè)問題是其 DLL 經(jīng)常需要一段時(shí)間才能啟動,,尤其是在它們都以托管代碼編寫且公共語言運(yùn)行庫 (CLR) 還未加載時(shí),。安裝了若干加載項(xiàng)的用戶會在每次啟動 Office 應(yīng)用程序時(shí)察覺到嚴(yán)重的性能問題。具有諷刺意味的是,,用戶可能根本不會在任何特定會話中用到其中的大多數(shù)加載項(xiàng),,但他們卻需要在所有操作中付出代價(jià)。
由于低速會對 Office 和加載項(xiàng)產(chǎn)生負(fù)面影響,,因此 Office 為 COM 加載項(xiàng)提供了稱為按需加載的功能,。此功能在 2007 Office 版本中已進(jìn)行了升級,并被擴(kuò)展以包括 RibbonX 支持,。其過程的概述如下,。加載項(xiàng)編寫者將加載項(xiàng)的 LoadBehavior 注冊表項(xiàng)設(shè)置為 ConnectFirstTime (16)。安裝加載項(xiàng)后第一次啟動應(yīng)用程序時(shí),,即會啟動加載項(xiàng),。Office 在加載項(xiàng)中查詢其 RibbonX XML 并將它緩存在磁盤上。RibbonX 然后調(diào)用加載項(xiàng)的所有 Get 回調(diào),,以便加載其所有圖像并緩存加載項(xiàng)的初始狀態(tài),。
關(guān)閉時(shí),加載項(xiàng)的注冊表項(xiàng)將更改為 DemandLoad,。在應(yīng)用程序的后續(xù)啟動中,,加載項(xiàng)將不啟動,但會顯示其 RibbonX UI,,就像已加載了一樣,。用戶只要一單擊加載項(xiàng)的按鈕之一,即會載入加載項(xiàng)以執(zhí)行用戶的命令,。
按需加載對最終用戶而言是透明的,,除了設(shè)置注冊表項(xiàng)外,開發(fā)人員不需要進(jìn)行任何其他工作,。(您可將此與使用 CommandBars 通過設(shè)置 <!ProgID> 字符串來使用按需加載的麻煩程度相比較,。)顯然,按需加載并非對每個(gè)加載項(xiàng)都適用,,但對于只將單個(gè)按鈕或菜單項(xiàng)添加到 UI 然后在單擊所添加項(xiàng)時(shí)激活其功能的大多數(shù)加載項(xiàng)而言,,它相當(dāng)有用。然而,,需要在用戶與其 UI 交互之前運(yùn)行復(fù)雜代碼的較復(fù)雜加載項(xiàng)無法使用按需加載,,因?yàn)樗鼈冃枰M(jìn)行加載以運(yùn)行代碼。

將 Word 模板升級到 RibbonX
剛才我們已介紹了 RibbonX 的所有主要功能,,現(xiàn)在讓我們用一些示例加載項(xiàng)和代碼段來做進(jìn)一步的深入研究,。首先,讓我們看看許多開發(fā)人員在切換到 2007 Office 系統(tǒng)時(shí)將會遇到的情況:將舊式加載項(xiàng)從 CommandBars 升級到 RibbonX。
我要升級的加載項(xiàng)是相當(dāng)簡單的 Word 模板 (.dot),,該模板用于將空白頁插入法律文檔,,并將標(biāo)準(zhǔn)(且自相矛盾)的“This page intentionally left blank”(本頁故意留為空白)文本填入該頁面。
使用文檔附加的 CommandBars 中“Insert”(插入)菜單上的按鈕來實(shí)現(xiàn)該加載項(xiàng),。按鈕的 OnAction 屬性被設(shè)置為 InsertBlankPage,,這是包含以下代碼的 Visual Basic? for Applications (VBA) 宏:
Sub InsertBlankPage()
    ' 插入一個(gè)空白頁面
    Selection.InsertBreak Type:=wdPageBreak
    Selection.ParagraphFormat.Alignment = wdAlignParagraphCenter
    Selection.Font.Size = 14
    Selection.Font.Color = wdColorGray50
    Selection.Font.Name = "Arial Black"
    Selection.TypeText Text:="有意將此頁面留為空白"
    Selection.InsertBreak Type:=wdPageBreak
End Sub
顯然它并不非常復(fù)雜,因?yàn)檫@只是一個(gè)演示版,。此文件可以從 MSDN? 雜志網(wǎng)站下載,。您可以使用“Templates”(模板)和“Add-Ins”(加載項(xiàng))對話框?qū)⑺惭b為全局模板。
將舊式 CommandBar 加載項(xiàng)升級到新 2007 Office 系統(tǒng) UI 的第一步是將舊 UI 映射到新模型中,。由于功能區(qū)會取代所有的工具欄和菜單,,要立即找到最適合加載項(xiàng) UI 的位置并不容易。
因此在要進(jìn)行此操作之前,,先停下來考慮一下并問您自己“我們真的需要升級此加載項(xiàng)嗎,?”在多數(shù)情況下,如果預(yù)算緊張,,答案可能是“不需要”,。如果您在 Word 2007 中加載該加載項(xiàng),那么它可以在“Add-Ins”(加載項(xiàng))選項(xiàng)卡中正常工作(請參見圖 5),。
圖 5 舊式加載項(xiàng) 
它在該處的工作并沒有特別不對勁的地方,,但您可能不喜歡它與所有其他的舊式加載項(xiàng)都保留在“Menu Commands”(菜單命令)組中,而且它不使用 RibbonX 的任何新功能,。它也不是一個(gè)優(yōu)秀的示范,,我們不能就此結(jié)束,所以讓我們繼續(xù),。
由于該加載項(xiàng)將頁插入到文檔中,,因此 UI 可能最好位于“Insert”(插入)選項(xiàng)卡上。如果該加載項(xiàng)將文檔作為一個(gè)整體進(jìn)行操控,,則可選擇將其 UI 放置在 Office 菜單中,。如果在現(xiàn)有 UI 中沒有適合它的位置,則“Add-Ins”(加載項(xiàng))選項(xiàng)卡上的自定義組是一個(gè)不錯(cuò)的選擇(避免創(chuàng)建只有一個(gè)按鈕的選項(xiàng)卡),。
Word 的內(nèi)置“Insert”(插入)選項(xiàng)卡包含一個(gè)用于插入頁的組,,而且它已經(jīng)包含一個(gè)用于插入空白頁的按鈕(2007 Office 版本的一個(gè)新功能)。由于舊式加載項(xiàng)還會插入“Intentionally Blank”(故意留為空白)占位文本,,我希望將其與內(nèi)置功能區(qū)分開,。讓我們將一個(gè)名為“Legal Pages”(法律頁)的自定義組插入到另一個(gè)組的旁邊,而且添加一個(gè)具有指示性圖標(biāo)的大按鈕,。圖 6 顯示了其完成時(shí)的外觀,。
圖 6 插入頁加載項(xiàng) 
下一步是拿出生成所需結(jié)果的 XML 文件,。在演示中,先給出最終產(chǎn)品再解釋其工作方式通常是最快速直觀的方法,。本著此精神,我們在圖 7 中給出了最終的 XML,。
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui">
  <ribbon>
    <tabs>
      <tab idMso="TabInsert">
        <group id="LegalGroup" label="法律條文頁面" 
               insertAfterMso="GroupInsertPages">
          <button id="BlankPageButton" label="有意留為空白頁面"
                  size="large" image="BlankIcon"/>
    </group>
   </tab>
  </tabs>
 </ribbon>
</customUI>

如您所見,,它相當(dāng)簡單。根標(biāo)記為 <customUI> 并指定 2007 Office 系統(tǒng) RibbonX XML 命名空間開始,。然后,,仔細(xì)檢查反映 UI 結(jié)構(gòu)的一系列標(biāo)記:Ribbon > Tabs > Tab > Group > Button。
第一個(gè)有趣的項(xiàng)是 <tab> 標(biāo)記上的 idMso="TabInsert" 屬性,。XML 中的所有控件都必須具有 ID 屬性以標(biāo)識它們,。內(nèi)置控件使用 idMso 以顯示它們是 Office 控件并將它們與使用 id 屬性的自定義控件區(qū)分。因此,,XML 文件實(shí)際上是在表示“查找內(nèi)置‘Insert’(插入)選項(xiàng)卡并在其內(nèi)部創(chuàng)建自定義組”,。insertAfterMso="GroupInsertPages" 屬性表示“將此組插入內(nèi)置‘Pages’(頁)組之后”。最后,,按鈕 id="BlankPageButton" 表示“在組內(nèi)部創(chuàng)建一個(gè)自定義按鈕”,。
在此示例中,組和按鈕的標(biāo)簽是在 XML 中靜態(tài)指定的,,因此它們永遠(yuǎn)不會更改,。在本例中這樣沒有問題,但如果您希望動態(tài)更改標(biāo)簽(可能出于本地化目的),,您可以改用 getLabel 屬性來指定要返回標(biāo)簽的函數(shù),。
最后一個(gè)有趣的部分是 image="BlankIcon" 屬性。它指示 RibbonX 在 Word 模板文件中搜索具有該 ID 的圖像,。在插入 XML 的同時(shí)您需要將該圖像粘貼在該文件中,。

添加 XML 和圖像
僅 2007 Office 版本的新文件格式支持附加的 RibbonX XML,因此您需要做的第一件事就是打開 .dot 文件,,然后將其另存為 .dotm 文件(添加的“m”意味著文件具有宏),。接下來,使用 .zip 擴(kuò)展名重命名文件并將其打開以檢查內(nèi)容,,如圖 8 所示,。
圖 8 文檔模板內(nèi)部 (單擊該圖像獲得較大視圖)
Open XML 文件格式會在另一篇文章中詳細(xì)介紹,在此處我們可以將它簡單概括為:包含以各種方式彼此相關(guān)的一批文件的壓縮包,。在此示例中,,document.xml 是主 Word 文檔,它與樣式信息,、VBA 代碼以及附加的 CommandBars 等各種內(nèi)容相關(guān),。由于我不想再讓文件具有附加的 CommandBars,,因此我們將 attachedToolbars.bin 文件從 .zip 文件中刪除,然后再重新打包,。
我們可以手動編輯 .zip 文件以插入 RibbonX XML 和圖標(biāo)圖像,,但用工具來執(zhí)行此操作會容易得多,所以我們選擇使用工具,。在 上,,有一大堆可用來處理 Open XML 文件格式的工具。您所需要的是名為 Custom UI Editor 的工具,。
Custom UI Editor 是一款方便小巧的工具,,可用來將 RibbonX XML 和相關(guān)聯(lián)的圖像插入到 Open XML 格式文件中。使用它打開 .dotm 文件,,然后粘貼到 XML 中并插入圖像(請參見圖 9),。保存文件。如果您很好奇,,您可以將它作為 .zip 文件打開,,然后會看到該工具分別在創(chuàng)建了 XML 文件 \customUI\customUI.xml 和圖像 \customUI\images\BlankIcon.png。它還修改了幾個(gè) rels 關(guān)系以指向這些新文件,。
圖 9 編輯模板 (單擊該圖像獲得較大視圖)
如果您在 Word 中打開該文件,,現(xiàn)在您將看到新按鈕,但在單擊時(shí)它不執(zhí)行任何操作,。這是顯而易見的,,因?yàn)槟€未告訴它要調(diào)用哪個(gè)宏。要執(zhí)行此操作,,將此處以紅色顯示的屬性添加到 XML:
<button id="BlankPageButton" label="有意留為空白頁面" 
        size="large" image="BlankIcon"
        onAction="RibbonXOnAction" tag="InsertBlankPage" />
剛開始,,您可能會感到奇怪,不明白為什么引入一個(gè)名為 RibbonXOnAction 的新宏,,而不是重用 InsertBlankPage 宏,。我這樣做的原因是 RibbonX OnAction 宏所具有的簽名與其 CommandBar 對應(yīng)部分的簽名不同。如果您有許多宏,,則您需完全手動來更改它們,,這既費(fèi)時(shí)又易產(chǎn)生錯(cuò)誤。而且它會破壞代碼,,從而無法在 Office 的先前版本上運(yùn)行,。
通過使新 RibbonX 宏調(diào)用舊 CommandBar 宏,則可以避免這兩個(gè)問題,。此時(shí),,引入標(biāo)記屬性:它是不在 UI 中使用的字符串屬性,但其被傳遞到加載項(xiàng)的代碼以供在那里使用,。以下是在 RibbonXOnAction 宏中使用它的方式,,您可以將下列代碼粘貼到新 VBA 模塊中:
Sub RibbonXOnAction(button As IRibbonControl)
    Application.Run button.Tag
End Sub
RibbonX OnAction 宏采用 IRibbonControl 對象作為參數(shù),,代表被單擊的按鈕。在 CommandBars 中,,OnAction 宏沒有參數(shù),,因此要指出被單擊的按鈕有時(shí)會顯得比較困難。IRibbonControl 對象提供 ID 和 Tag 屬性以解決 RibbonX 中的此問題,。
將此宏放置在適當(dāng)?shù)奈恢煤?,特別的新按鈕即會開始工作!這就是使用 RibbonX 來升級此加載項(xiàng)的代碼以運(yùn)行而要做的全部工作:一個(gè)新的單行宏,,且不對現(xiàn)有代碼進(jìn)行任何更改,。太精彩了,。

Excel 的 COM 加載項(xiàng)
在第二個(gè)示例中,,我們將執(zhí)行一些稍微復(fù)雜的工作并為 Excel? 編寫一個(gè) COM 加載項(xiàng)。該加載項(xiàng)是一個(gè)小型的業(yè)務(wù)線 (LOB) 應(yīng)用程序,,用于填寫和提交時(shí)間卡片,。限于篇幅,我僅在此處提供部分代碼,,完整源代碼可在代碼下載中找到,。
第一步仍是指出所需要的 UI 種類。該加載項(xiàng)允許用戶創(chuàng)建時(shí)間卡片,,然后編輯并提交它們,。因?yàn)閯傞_始需要顯示的時(shí)間卡片 UI 只有“New Timecard”(新建時(shí)間卡片)按鈕,因此請將其放置在 Office 菜單上(請參見圖 10),。
圖 10 新按鈕 
單擊“New Timecard”(新建時(shí)間卡片)按鈕后(或打開現(xiàn)有時(shí)間卡片后),,即會在自定義選項(xiàng)卡中顯示其余時(shí)間卡片 UI。由于“Page Layout”(頁面布局),、“Formulas”(公式),、“Review”(審閱)和“Data”(數(shù)據(jù))等各種 Excel 選項(xiàng)卡不能應(yīng)用于填寫時(shí)間卡片,請同時(shí)隱藏這些選項(xiàng)卡(請參見圖 11),。
圖 11 自定義時(shí)間卡片功能區(qū)選項(xiàng)卡 (單擊該圖像獲得較大視圖)
時(shí)間卡片 UI 明顯比先前的加載項(xiàng) UI 復(fù)雜得多,,而創(chuàng)建它的是 XML,如圖 12 中所示,。COM 加載項(xiàng)需要使用 RibbonX 做的第一件事就是實(shí)現(xiàn) IRibbonExtensibility 界面,。幸運(yùn)的是,Visual Studio? IntelliSense? 功能可以輕松地實(shí)現(xiàn)這一點(diǎn),。創(chuàng)建一個(gè)加載項(xiàng),,方法是選擇 Visual Studio 中的“新建項(xiàng)目”,轉(zhuǎn)到“其他項(xiàng)目類型”類別,,然后選擇“擴(kuò)展性”部分中的“共享的外接程序”,。
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui"
          onLoad="OnLoad" loadImage="LoadImage">
  <ribbon>
    <officeMenu>
      <button id="NewTimecard" insertAfterMso="FileNew" 
              label="新建時(shí)間卡片" imageMso="StartAfterPrevious"
              onAction="NewTimecard" />
    </officeMenu>
    <tabs>
      <tab id="TimecardTab" label="Timecard"
           getVisible="IsCustomTabVisible">
        <group id="EditingTools" label="編輯工具">
          <button id="ClearTimecard" label="清除時(shí)間卡片" size="large" 
                  imageMso="TableDeleteRowsAndColumnsMenuWord"
                  onAction="ClearTimecard"/>
          <button id="InsertDay" label="插入新的一天" size="large"
                  imageMso="CellsInsertDialog" onAction="InsertNewDay"/>
          <button id="CalculateTotal" label="計(jì)算工作時(shí)間" 
                  size="large" imageMso="SlideShowRehearseTimings" 
                  onAction="CalculateHours"/>
        </group>
        <group id="WageTools" label="工資工具">
          <editBox id="Wage" label="計(jì)時(shí)工資:"
                   image="dollar1.png" onChange="OnWageChanged"
                   getText="GetWage"/>
          <editBox id="Overtime" label="加班獎(jiǎng)金:"
                   image="dollar2.png" onChange="OnOvertimeChanged"
                   getText="GetOvertime"/>
          <button id="CalculatePay" label="計(jì)算報(bào)酬" 
                  size="large" imageMso="AcceptInvitation" 
                  onAction="CalculatePay"/>
        </group>
        <group id="SubmissionTools" label="提交工具">
          <button id="SignTimecard" label="簽署時(shí)間卡片" 
                  size="large" image="signature.png" 
                  onAction="SignTimecard"/>
          <button id="SubmitTimecard" label="提交時(shí)間卡片" 
                  size="large" image="submit.png" 
                  onAction="SubmitTimecard" getEnabled="IsTimecardSigned"
                  screentip="確保在提交之前簽署時(shí)間 
                            卡片" />
        </group>
      </tab>
      <tab idMso="TabPageLayoutExcel" getVisible="IsBuiltinTabVisible"/>
      <tab idMso="TabData" getVisible="IsBuiltinTabVisible" />
      <tab idMso="TabReview" getVisible="IsBuiltinTabVisible" />
      <tab idMso="TabFormulas" getVisible="IsBuiltinTabVisible" />
    </tabs>
  </ribbon>
</customUI>

依次點(diǎn)擊此對話框以及隨后顯示的向?qū)?。您需要設(shè)置各種選項(xiàng),例如您的加載項(xiàng)應(yīng)安裝在哪些 Office 應(yīng)用程序中,,以及要使用哪種編程語言,。在此示例中,我選擇使用 C#,。
在創(chuàng)建加載項(xiàng)后,,您應(yīng)看到 Connect 類,該類實(shí)現(xiàn)標(biāo)準(zhǔn)的 COM 加載項(xiàng) IDTExtensibility2 界面,。這是您需要實(shí)現(xiàn) IribbonExtensibility 的對象,。添加此界面并讓 Visual Studio 自動為您實(shí)現(xiàn)其方法。您最后應(yīng)以與下面類似的代碼結(jié)束:
using Office = Microsoft.Office.Core;
[GuidAttribute("E8407539-C642-43BB-8FCB-2E27A46179DE"), 
 ProgId("TimecardAddin.Connect")]
public class Connect : Object, Extensibility.IDTExtensibility2, 
    Office.IRibbonExtensibility
{
    public string GetCustomUI(string RibbonID)
    {
        throw new Exception("未實(shí)現(xiàn),。");
    }

    // IDTExtensibility 方法
}
IRibbonExtensibility 的唯一方法是 GetCustomUI,,該方法將 RibbonX XML 作為字符串返回。它使用 RibbonID 參數(shù),,該參數(shù)與“Microsoft.Word.Document”或“Microsoft.Excel.Workbook”字符串類似,,而且主要用于編寫在多個(gè)應(yīng)用程序或具有多種類型功能區(qū)的應(yīng)用程序(例如 Microsoft Outlook)中運(yùn)行的加載項(xiàng)。
如果您將 XML 文件作為名為 customui.xml 的“Embedded Resource”(嵌入資源)添加到項(xiàng)目中,,您可以使用與下列類似的代碼從 GetCustomUI 中將其返回:
public string GetCustomUI(string RibbonID)
{
    Assembly assembly = Assembly.GetExecutingAssembly();
    using(Stream stream = assembly.GetManifestResourceStream(
        "TimecardAddin.customui.xml"))
    {
        return new StreamReader(stream).ReadToEnd();
    }
}
此時(shí),,您可以構(gòu)建加載項(xiàng)并安裝它。啟動 Excel 后,,您應(yīng)看到自定義 UI,,但自定義圖像未加載以及單擊按鈕不執(zhí)行任何操作的情況除外。
XML 中所引用的所有回調(diào)函數(shù)都將調(diào)用失敗,,由于您還未實(shí)現(xiàn)它們,。如果啟用應(yīng)用程序選項(xiàng)對話框的“Advanced”(高級)部分中的“Show add-in user interface errors”(顯示加載項(xiàng)用戶界面錯(cuò)誤)選項(xiàng),您將會看到一系列關(guān)于回調(diào)失敗的錯(cuò)誤消息,。您應(yīng)確保在開發(fā) RibbonX 加載項(xiàng)時(shí)檢查此選項(xiàng),。這樣,在加載項(xiàng)出現(xiàn)問題時(shí),,您便會收到向您發(fā)出警報(bào)的大量錯(cuò)誤消息,。顯示的第一條錯(cuò)誤消息解釋“onLoad”回調(diào)運(yùn)行失敗的原因,因此我們先實(shí)現(xiàn)這個(gè)函數(shù),。

實(shí)現(xiàn)回調(diào)函數(shù)
功能區(qū)中的根 <customUI> 標(biāo)記具有可選的 onLoad 回調(diào),,加載項(xiàng)可以實(shí)現(xiàn)該回調(diào)以獲得對 IRibbonUI 對象的引用。IRibbonUI 對象用于使緩存的回調(diào)返回值無效,,而無論何時(shí)需更改加載項(xiàng) UI 的狀態(tài),。我馬上就會詳細(xì)介紹如何使用它,目前暫時(shí)先將其塞入到成員變量中,。將此代碼添加到 Connect 類:
Office.IRibbonUI m_Ribbon;

public void OnLoad(Office.IRibbonUI ribbon)
{
    m_Ribbon = ribbon;
}
<customUI> 標(biāo)記上的另一個(gè)可選回調(diào)是 loadImage,,該回調(diào)是 COM 加載項(xiàng)為其控件加載圖標(biāo)的方式,。這就是 XML 中的 image="dollar1.png" 行起作用的位置。對于圖像屬性中指定的每個(gè)字符串,,RibbonX 都會調(diào)用 loadImage 以加載該圖像,。
可以用加載項(xiàng)所希望的任何方式來存儲圖像,但在此示例中,,讓我們像使用 XML 那樣將圖像作為嵌入的資源進(jìn)行添加,。假定您已將 dollar1.png 作為資源添加到 TimecardAddin 程序集中,下面便是實(shí)現(xiàn) loadImage 回調(diào)的方法:
public Bitmap LoadImage(string imageName)
{
    Assembly assembly = Assembly.GetExecutingAssembly();
    Stream stream = assembly.GetManifestResourceStream(
        "TimecardAddin." + imageName);
    return new Bitmap(stream);
}
關(guān)于此函數(shù),,有幾個(gè)有趣的地方值得注意,。首先,它將 System.Drawing.Bitmap 對象作為圖像返回,。System.Drawing.Bitmap 是 2007 Office 版本的 RibbonX 支持的新功能,,而且是為托管加載項(xiàng)返回圖像的最簡單也是最推薦的方法。非托管(C++ 和 Visual Basic 6.0)加載項(xiàng)可以為其圖像返回 IPictureDisp 對象,,這些對象與 CommandBars 中所用對象的格式相同,。
要注意的第二件事是您返回的只是一個(gè)包含位圖數(shù)據(jù)和透明度數(shù)據(jù)的圖像,。我想您也發(fā)現(xiàn)了,,對!不必再為您的 Office 加載項(xiàng)創(chuàng)建兩個(gè)獨(dú)立的“圖片”和“掩碼”圖標(biāo),!有了 RibbonX,,Office 現(xiàn)在支持具有 alpha 通道的全 32 位圖標(biāo)。目前,,PNG 格式具有對 alpha 通道的最佳工具支持,,而且是 RibbonX 圖標(biāo)的建議格式。
您需要實(shí)現(xiàn)的下一組回調(diào)是內(nèi)置選項(xiàng)卡和自定義選項(xiàng)卡上的 getVisible 回調(diào),。內(nèi)置選項(xiàng)卡都使用 IsBuiltinTabVisible,,自定義選項(xiàng)卡則使用 IsCustomTabVisible,因?yàn)檫@兩個(gè)函數(shù)需要返回相反的值(編輯時(shí)間卡片時(shí)內(nèi)置選項(xiàng)卡應(yīng)隱藏,,而自定義選項(xiàng)卡應(yīng)顯示),。
通過將文件的 Category 屬性設(shè)置為 Timecard,加載項(xiàng)可以跟蹤特定的 Excel 工作簿是否為時(shí)間卡片,。不具有此屬性的文件將被忽略,。
IsBuiltinTabVisible 和 IsCustomTabVisible 函數(shù)都將使用幫助程序 IsTimecard 函數(shù):
public bool IsCustomTabVisible(Office.IRibbonControl tab) {
    return IsTimecard(tab.Context as Excel.Window);
}

public bool IsBuiltinTabVisible(Office.IRibbonControl tab) {
    return !IsTimecard(tab.Context as Excel.Window);
}
private bool IsTimecard(Excel.Window window)
{
    if (null == window) return false;

    Excel.Workbook workbook = (Excel.Workbook)window.Parent;
    Office.DocumentProperties properties = 
        (Office.DocumentProperties)workbook.BuiltinDocumentProperties;
    Office.DocumentProperty category = properties["Category"];

    return (null != category && null != category.Value && 
            category.Value.Equals("Timecard"));
}
此代碼使用被傳遞到 RibbonX 回調(diào)的 IRibbonControl 的 Context 屬性。在大多數(shù) Office 應(yīng)用程序中,,Context 屬性等于 Window 對象,。(Access 沒有 Window 對象,因此它在此處為 NULL,,而在 Outlook 中,,它等于 Inspector 對象,。)加載項(xiàng)應(yīng)使用 Window 對象來確定此 RibbonX 回調(diào)所引用的文檔,因?yàn)樗⒉皇冀K等于 Application.ActiveDocument 屬性,。Window 對象可以用于區(qū)分查看同一文檔的兩個(gè)不同窗口,。
從 Window 對象您可以得到 Workbook 對象,從 Workbook 對象則可以得到 Category 屬性并檢查它是否等于 Timecard,。

使 getVisible 回調(diào)值無效
如果您現(xiàn)在啟動 Excel,,您將看到自定義選項(xiàng)卡為隱藏,而內(nèi)置選項(xiàng)卡則為顯示,。這是正確的,,由于默認(rèn)文檔不是時(shí)間卡片。如果您打開一個(gè) Timecard 文檔,,選項(xiàng)卡將不會顯示,。為什么會這樣呢?
由于性能原因,,RibbonX 緩存來自 get 回調(diào)的返回值,。如果它不這樣做,它將一直回調(diào)加載項(xiàng)以防它需要切換其 UI 中的某項(xiàng),。加載項(xiàng)需要讓 Office 知道它何時(shí)想更改其 UI,。
在這種情況下,便可使用之前討論的 IRibbonUI 對象,。它包含兩個(gè)方法:Invalidate 和 InvalidateControl,。Invalidate 方法將使所有緩存的回調(diào)無效,而 InvalidateControl 方法則使用控件 ID 參數(shù)并只使特定自定義控件的緩存回調(diào)無效,。
無論何時(shí)在 Excel 中發(fā)生文檔切換,,您都需要使選項(xiàng)卡的 getVisible 回調(diào)值無效,因?yàn)榇藭r(shí)可能需要顯示 UI,。Excel 提供了 WorkbookActivate 事件,,您可以用它來實(shí)現(xiàn)此目的。在 OnStartupComplete 方法中為此事件添加一個(gè)處理程序:
public void OnStartupComplete(ref System.Array custom)
{
    excelApplication.WorkbookActivate += 
       new Excel.AppEvents_WorkbookActivateEventHandler(
           OnWorkbookActivate);
}

void OnWorkbookActivate(Excel.Workbook Wb)
{
    // 自定義選項(xiàng)卡可能需要在切換工作簿時(shí)變?yōu)榭梢姡?
    // 以使緩存的 getVisible 值無效
    m_Ribbon.Invalidate();
}
幸運(yùn)的是,,只要您一鍵入 += 字符,,Visual Studio IntelliSense 即會自動為您實(shí)現(xiàn)該事件處理程序,因此這很容易,。
現(xiàn)在如果您打開 Excel 并在 Timecard 文檔和另一文檔之間切換,,您將看到僅為時(shí)間卡片顯示自定義選項(xiàng)卡,而同時(shí)會隱藏內(nèi)置選項(xiàng)卡,。很好?,F(xiàn)在您只需要能夠使用加載項(xiàng)來首先創(chuàng)建時(shí)間卡片即可。
“New Timecard”(新建時(shí)間卡片)按鈕的回調(diào)相當(dāng)簡單:它使用前面所示相同的 OnAction 簽名。它創(chuàng)建一個(gè) Category 屬性等于 Timecard 的工作簿,,并設(shè)置默認(rèn)工作表:
public void NewTimecard(Office.IRibbonControl button)
{
    Excel.Workbook timecard = 
        excelApplication.Workbooks.Add(Missing.Value);
    Office.DocumentProperties properties =
        (Office.DocumentProperties)timecard.BuiltinDocumentProperties;
    properties["Category"].Value = "Timecard";
    Excel.Worksheet timesheet = 
        (Excel.Worksheet)timecard.Worksheets[1];
    NewTimesheet(timesheet);
}
它使用幫助程序函數(shù)來初始化工作簿的第一個(gè)工作表中的時(shí)間表(“Clear Timecard”(清除時(shí)間卡片)按鈕會調(diào)用同樣的函數(shù)),。

其他回調(diào)
其余的回調(diào)與“New Timecard”(新建時(shí)間卡片)按鈕的回調(diào)類似,因此我在此處未包括全部代碼,,但有幾點(diǎn)值得一提,。保存計(jì)時(shí)工資和加班乘數(shù)的 EditBox 比簡單按鈕稍微復(fù)雜些,因?yàn)樗鼈冃枰獌蓚€(gè)回調(diào)以確保工作正常,。以下是用于工資框的回調(diào):
double m_Wage = 5.25;

public void OnWageChanged(Office.IRibbonControl c, string wage)
{
    m_Wage = double.Parse(wage);
}

public string GetWage(Office.IRibbonControl c)
{
    return m_Wage.ToString();
}
只要用戶在工資框中鍵入新值,,即會調(diào)用 OnWageChanged。此示例只轉(zhuǎn)換并記錄新值,,但實(shí)際的加載項(xiàng)可能希望在接受新值之前,,對其進(jìn)行一些額外的邊界檢查和驗(yàn)證。
GetWage 方法為 EditBox 提供了初始值,。需要注意的重要一點(diǎn)是,,IRibbonUI 對象使 UI 無效時(shí)也會調(diào)用它。加載項(xiàng)不應(yīng)指望用戶輸入一直保留在 EditBox 內(nèi),,因此建議使用與此示例中(OnWageChanged 和 GetWage)類似的一對 onChanged 和 getText 來跟蹤當(dāng)前值,。
加載項(xiàng)將工資值作為成員變量存儲在加載項(xiàng)中,這沒有問題,,因?yàn)榇酥祵τ诩虞d項(xiàng)是全局的且并不特定于文檔,。如果此值與每個(gè)時(shí)間卡片關(guān)聯(lián),則您需要將該值存儲在與時(shí)間卡片相關(guān)聯(lián)的內(nèi)存中,,以便用戶在兩個(gè)時(shí)間卡片之間切換時(shí)可以正確地更新該值,。
另一個(gè)有趣的控件是“Sign Timecard”(簽署時(shí)間卡片)按鈕,。它彈出一個(gè)對話框,,供用戶輸入其姓名然后將此姓名寫入到時(shí)間卡片中:
public void SignTimecard(Office.IRibbonControl button)
{
    SignatureDialog sd = new SignatureDialog();
    if (DialogResult.OK == sd.ShowDialog())
    {
        string signature = sd.GetSignature();

        timesheet.get_Range("E" + (daycount + 5), 
        Missing.Value).Formula = signature;

        m_Ribbon.InvalidateControl("SubmitTimecard");
    }
}
它還調(diào)用 SubmitTimecard 按鈕上的 IRibbonUI.InvalidateControl?!癝ubmit”(提交)按鈕將禁用,,直到使用檢查簽名的 getEnabled 函數(shù)簽署了時(shí)間卡片。在簽名后,,您需要使此 getEnabled 返回值無效以重新啟用該按鈕,。
由于僅在單擊“Sign Timecard”(簽署時(shí)間卡片)按鈕時(shí),加載項(xiàng)才調(diào)用 InvalidateControl,,因此如果用戶手動將簽名鍵入到時(shí)間卡片單元格中,,則不會啟用“Submit”(提交)按鈕(如果用戶刪除其簽名,則會禁用該按鈕),。如果您希望此按鈕工作,,每當(dāng)簽名單元格被修改,我們都可以掛接 SheetChanged 事件,,然后調(diào)用 InvalidateControl,。

總結(jié)
這就是有關(guān) Timecard 加載項(xiàng)的所有內(nèi)容,。整個(gè)加載項(xiàng)僅有幾百行代碼,其中包括由 Visual Studio 自動生成的全部代碼,。不可否認(rèn),,它相當(dāng)簡陋,要實(shí)際應(yīng)用還需進(jìn)行大量的錯(cuò)誤檢查和代碼驗(yàn)證,,但它演示了使用 RibbonX 來利用 Office 作為您自己的應(yīng)用程序的平臺是多么容易,。如果您想親自嘗試一下,請下載源代碼,。
本文僅簡單介紹了 RibbonX 中的功能,,因此如果您需要更多詳細(xì)信息和示例代碼,請?jiān)L問 MSDN 上的官方頁面(英文),。該網(wǎng)頁上還有指向完整 RibbonX 文檔,、控件 ID 的列表、示例加載項(xiàng)和 RibbonX 相關(guān)博客的鏈接,。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多