Share via


建立功能區應用程式

Windows 功能區架構是由兩個相異但相依的開發平臺所組成:以可延伸應用程式標記語言為基礎的標記語言 (XAML) 宣告控制項及其視覺配置,以及 C++ 元件物件模型 (COM) 型介面集來定義命令功能和應用程式勾點。 功能區架構內的這個工作分工需要想要利用架構所提供的豐富 UI 功能的開發人員必須設計及描述標記中的 UI,然後使用功能區架構 COM 介面將架構連線到主應用程式。

功能區藍圖

功能區應用程式的視覺層面,例如顯示哪些控制項及其放置位置,都會在標記中宣告 (請參閱 使用功能區標記宣告命令和控制項) 。 應用程式命令邏輯會在程式碼中實作,例如按下按鈕時會發生什麼情況。

實作功能區並將其併入 Windows 應用程式的程式需要四個基本工作:撰寫標記、編譯標記、撰寫程式碼,以及編譯並連結整個應用程式。

下圖說明一般功能區實作的工作流程。

此圖顯示典型功能區實作的工作流程。

下列各節會更詳細地描述此程式。

撰寫標記

設計功能區 UI 之後,應用程式開發人員的第一個工作是使用功能區標記來描述 UI。

重要

功能區架構標記架構檔案 UICC.xsd 會隨適用于 Windows 7 和 .NET Framework 4.0 的 Microsoft Windows 軟體發展工具組) (SDK 安裝。 使用標準安裝路徑,檔案位於 %ProgramFiles%\Microsoft SDKs\Windows\[版本號碼]\Bin 資料夾中,許多 XML 編輯器可參考該資料夾以提供提示和自動完成。

 

功能區控制項、功能區命令 (控制項獨立元素,以提供功能區控制項的基底功能) ,而且所有控制項配置和視覺關聯性都會在標記中宣告。 功能區標記的結構強調透過兩個主要節點階層的功能區控制項和命令之間的差異: 命令和資源 樹狀結構以及 檢視 樹狀結構。

功能區公開的所有容器和動作都會在 命令和資源 樹狀結構中宣告。 每個 Command 元素都會與一組資源相關聯,因為 UI 設計需要。

建立應用程式的命令之後,您會在 Views 樹狀結構中宣告控制項,並將每個控制項系結至命令以公開 Command 功能。 功能區架構會根據這裡所宣告的控制項階層來決定控制項的實際位置。

下列程式碼範例說明如何宣告 Button 控制項、標示為 Exit 應用程式,並將它與 Exit Command 產生關聯。

<Application xmlns="http://schemas.microsoft.com/windows/2009/Ribbon">
  <Application.Commands>
    <Command Name="cmdExit" LabelTitle="Exit application" />
  </Application.Commands>

  <Application.Views>
    <Ribbon>
      <Ribbon.Tabs>
        <Tab>
          <Group>
            <Button CommandName="cmdExit" />
          </Group>
        </Tab>
      </Ribbon.Tabs>
    </Ribbon>
  </Application.Views>
</Application>
        

提示

雖然可以針對功能區標記檔案使用任何副檔名,但.xml是在整個檔中使用的建議副檔名。

 

編譯標記

建立功能區標記檔案之後,功能區標記編譯器、UI 命令編譯器 (UICC) 必須編譯成二進位格式,Windows 軟體發展工具組 (SDK) 。 此二進位檔案的參考會在主應用程式初始化功能區架構期間傳遞至 IUIFramework::LoadUI 方法。

UICC 可以直接從命令列視窗執行,或在 Visual Studio 中新增為「自訂建置步驟」。

下圖顯示 Windows 7 SDK CMD Shell 視窗中的 UICC 標記編譯器。

顯示命令列視窗中uicc.exe的螢幕擷取畫面。

下圖顯示 VISUAL Studio 中新增為自訂建置步驟的 UICC。

顯示 visual Studio 中新增uicc.exe為自訂建置步驟的螢幕擷取畫面。

UICC 會產生三個檔案:標記的二進位版本 (.bml) 、識別碼定義標頭 (.h 檔案) 公開標記元素給功能區主機應用程式,以及 資源定義腳本 (.rc 檔案) ,以在編譯時期將功能區映射和字串資源連結至主應用程式。

如需編譯功能區架構標記的詳細資訊,請參閱 編譯功能區標記

建置應用程式

在標記中設計及實作功能區應用程式的初步 UI 之後,必須撰寫應用程式程式碼以初始化架構、取用標記,並將標記中所宣告的命令系結至應用程式中的適當 Command 處理常式。

重要

由於功能區架構是以 COM 為基礎,因此建議功能區專案使用 __uuidof () 運算子來參考功能區架構介面的 GUID (IID) 。 在這些情況下,無法使用 __uuidof () 運算子,例如使用非 Microsoft 編譯器或以 C 為基礎的主應用程式時,應用程式必須定義 IID,因為它們未包含在 uuid.lib 中。

如果應用程式定義了 IID,則必須使用 UIRibbon.idl 中指定的 GUID。

UIRibbon.idl 隨附于 Windows 軟體發展工具組 (SDK) ,而且可以在 %ProgramFiles%\Microsoft SDKs\Windows\v7.0\Include 的標準安裝路徑中找到。

 

初始化功能區

下圖說明實作簡單功能區應用程式所需的步驟。

此圖顯示實作簡單功能區實作所需的步驟。

下列步驟詳細說明如何實作簡單的功能區應用程式。

  1. CoCreateInstance

    應用程式會使用功能區架構類別識別碼呼叫標準 COM CoCreateInstance 函式,以取得架構的指標。

    IUIFramework* pFramework = NULL;
    HRESULT hr = ::CoCreateInstance(
                CLSID_UIRibbonFramework, 
                NULL,
                CLSCTX_INPROC_SERVER, 
                IID_PPV_ARGS(&pFramework));
    if (FAILED(hr))
    {
      return hr;
    }
    
  2. 初始化 (hwnd、IUIApplication*)

    應用程式會呼叫 IUIFramework::Initialize,並傳入兩個參數:最上層視窗的控制碼,其中包含功能區,以及 IUIApplication 實作 的指標,可讓架構對應用程式進行回呼。

    ![重要]
    功能區架構會初始化為單一線程 Apartment (STA) 。

     

    hr = pFramework->Initialize(hWndHost, pApplication);
    if (FAILED(hr))
    {
      return hr;
    }
    
  3. LoadUI (實例 resourceName)

    應用程式會呼叫 IUIFramework::LoadUI 來系結標記資源。 此函式的第一個參數是功能區應用程式實例的控制碼。 第二個參數是先前編譯的二進位標記資源名稱。 藉由將二進位標記傳遞至功能區架構,應用程式會發出功能區結構應該是什麼,以及應該如何排列控制項。 它也會提供架構資訊清單,以公開 (,例如貼上、剪下、尋找) ,當架構在執行時間進行命令相關的回呼時,架構會使用此資訊清單。

    hr = pFramework->LoadUI(GetModuleHandle(NULL), L"APPLICATION_RIBBON");
    if (FAILED(hr))
    {
      return hr;
    }
    
  4. IUIApplication::OnCreateUICommand 回呼

    完成步驟 1 到 3 之後,功能區架構就會知道功能區中要公開的命令。 不過,架構在功能區正常運作之前仍需要兩件事:在執行時間執行命令時告訴應用程式,以及取得命令資源或屬性的方法。 例如,如果下拉式方塊要出現在 UI 中,則架構必須要求要填入下拉式方塊的專案。

    這兩項功能是透過 IUICommandHandler 介面來處理。 具體來說,針對二進位標記中所宣告的每個命令,請參閱上述步驟 3 () ,架構會呼叫 IUIApplication::OnCreateUICommand 來要求應用程式輸入該命令的 IUICommandHandler 物件

    注意

    IUICommandHandler介面可讓 Command 處理常式系結至一或多個命令。

     

應用程式至少必須實作傳回E_NOTIMPL的 IUIApplication 方法存根,如下列範例所示。

STDMETHOD(OnViewChanged)(UINT32 viewId,
                         UI_VIEWTYPE typeID,
                         IUnknown *view,
                         UI_VIEWVERB verb,
                         INT32 uReasonCode)
{ 
  return E_NOTIMPL; 
}

STDMETHOD(OnCreateUICommand)(UINT32 commandId,
                             UI_COMMANDTYPE typeID,
                             IUICommandHandler **commandHandler)
{ 
  return E_NOTIMPL; 
}

STDMETHOD(OnDestroyUICommand)(UINT32 commandId,
                              UI_COMMANDTYPE typeID,
                              IUICommandHandler *commandHandler) 
{ 
  return E_NOTIMPL; 
}

此時,標記資源檔必須連結至主應用程式,方法是包含標記資源定義檔案的參考 (,其中包含應用程式資源檔中標記標頭檔) 的參考。 例如,名為 RibbonApp 的應用程式,其資源檔稱為 ribbonUI.rc 需要 RibbonApp.rc 檔案中的下一行。

#include "ribbonUI.rc"

根據所使用的編譯器和連結器,資源定義腳本可能需要編譯,才能編譯功能區應用程式。 資源編譯器 (RC) 隨附于 Microsoft Visual Studio 和 Windows SDK 的命令列工具,可用於這項工作。

編譯應用程式

一旦編譯功能區應用程式,就可以執行並測試 UI。 如果 UI 需要調整,且核心應用程式程式碼中任何相關聯的 Command 處理常式沒有任何變更,請修改標記來源檔案、使用UICC.exe重新編譯標記,以及連結新的標記資源檔。 重新開機應用程式時,會顯示修改過的 UI。

這完全不需要觸碰核心應用程式程式碼,對標準應用程式開發和散發有顯著改善。

執行時間更新和執行

功能區架構的執行時間通訊結構是以推入和提取或雙向呼叫端模型為基礎。

此模型可讓架構在執行命令時通知應用程式,並允許架構和應用程式查詢、更新及使屬性值和功能區資源失效。 這項功能是透過許多介面和方法提供。

架構會透過 IUICommandHandler::UpdateProperty 回呼方法,從功能區應用程式提取更新的屬性資訊。 命令識別碼和屬性索引鍵,可識別要更新的 Command 屬性會傳遞至方法,然後傳回或推送該屬性索引鍵至架構的值。

架構會在執行 Command 時呼叫IUICommandHandler::Execute,識別命令識別碼和 (UI_EXECUTIONVERB) 所發生的執行類型。 這是應用程式指定命令的執行邏輯的位置。

下圖說明架構與應用程式之間命令執行的執行時間通訊。

此圖顯示功能區架構與主應用程式之間的執行時間通訊範例。

注意

不需要實作 IUICommandHandler::UpdatePropertyIUICommandHandler::Execute 函式,一開始在應用程式中顯示功能區。 不過,這些方法是確保應用程式在使用者執行命令時正確運作的必要方法。

 

OLE 支援

功能區應用程式可以設定為 OLE 伺服器,以支援就地 OLE 啟用。

在 OLE 伺服器應用程式中建立的物件會在插入 (貼上或放置) 于 OLE 用戶端應用程式 (或容器) 時,維護其與伺服器應用程式的關聯。 在就地 OLE 啟用中,按兩下用戶端應用程式中的 物件會開啟伺服器應用程式的專用實例,並載入物件以進行編輯。 關閉伺服器應用程式時,對 物件所做的所有變更都會反映在用戶端應用程式中。

注意

功能區架構不支援就地 OLE 啟用。 無法在 OLE 用戶端應用程式內編輯功能區型 OLE 伺服器中建立的物件。 需要伺服器應用程式的外部專用實例。

使用功能區標記宣告命令和控制項

功能區使用者體驗指導方針

功能區設計程式