說明功能表合併
當物件在容器內使用時,OLE Documents 的功能表合併通訊協定會提供物件完整控制 [說明 ] 功能表。 因此,除非使用者停用該物件,否則容器的說明主題無法使用。 現用文件內含項目結構會在就地功能表合併的規則展開,讓容器和作用中現用文件共用功能表。 新規則只是額外的慣例,內容是關於哪些元件擁有功能表的哪些部分,以及共用功能表如何建構。
新的慣例很簡單。 在使用中檔中,[ 說明 ] 功能表有兩個最上層功能表項目,依下列方式組織:
Help
Container Help >
Object Help >
例如,當 Word 區段在 Office Binder 中使用時,[ 說明 ] 功能表會顯示如下:
Help
Binder Help >
Word Help >
兩個功能表項目為串聯功能表,其底下容器和物件特有的任何其他功能表項目皆提供給使用者。 這裡顯示的項目視容器和物件而有所不同。
若要建構此合併 的說明功能表,使用中檔內含專案架構會修改一般的 OLE Documents 程式。 根據 OLE Documents,合併的功能表列可以有六組功能表,即 [檔案 ]、[編輯 ]、 [容器 ] 、 [物件 ]、[視窗 ]、 [說明 ] 依該順序排列。 在每個群組中,可以是零或多個功能表。 檔案 、 容器 和 視窗 群組 屬於容器,而 Edit 、 Object 和 Help 群組 屬於物件。 當物件要進行功能表合併時,它會建立一個空白的功能表列並且將其傳遞至容器。 然後,容器會藉由呼叫 IOleInPlaceFrame::InsertMenus
來插入其功能表。 物件也會傳遞結構,其為六個 LONG 值的陣列( OLEMENUGROUPWIDTHS )。 在插入功能表之後,容器會標示其每個群組中新增了多少功能表,然後傳回。 接著,物件插入其功能表,並請注意各個容器群組中的功能表計數。 最後,物件會將合併的功能表列和陣列 (包含每個群組中的功能表計數) 傳遞至 OLE,而其會傳回不透明「功能表描述元」控制代碼。 之後,物件會透過 IOleInPlaceFrame::SetMenu
傳遞該控制碼和合併功能表列至容器。 此時,容器會顯示合併的功能表列並且將控制代碼傳遞至 OLE,因此 OLE 可以適當分派功能表訊息。
在修改的作用中檔程式中,物件必須先將 OLEMENUGROUPWIDTHS 元素初始化為零,再將它傳遞至容器。 然後容器會執行一般功能表插入,但有一個例外狀況:容器會將 [說明 ] 功能表插入為最後一 個專案,並將值儲存在 OLEMENUGROUPWIDTHS 陣列的最後(第六個)專案中 (也就是 width[5],屬於物件的說明群組)。 此 [說明 ] 功能表只會有一個子功能表的專案,如先前所述,[ 容器說明 > ] 串聯功能表。
然後物件會執行其一般功能表插入程式碼,但插入其 [說明 ] 功能表之前,它會檢查 OLEMENUGROUPWIDTHS 陣列的第六個專案 。 如果值為 1,且最後一個功能表的名稱是 [說明 ] (或適當的當地語系化字串),則物件會 將其 [說明] 功能表插入為容器 [說明 ] 功能表的 子功能表。
然後,物件會將 OLEMENUGROUPWIDTHS 的第 六個元素設定為零,並將第五個專案遞增一個。 這可讓 OLE 知道 [ 說明 ] 功能表屬於容器,而對應至該功能表的功能表訊息(及其子功能表)應該路由傳送至容器。 接著,容器必須負責轉送WM_INITMENUPOPUP、WM_SELECT、WM_COMMAND和其他屬於 [說明 ] 功能表部分 的功能表相關訊息。 這可藉由使用 WM_INITMENU 來清除旗標,告知容器使用者是否已流覽至物件的 [說明 ] 功能表。 然後,容器會 監看WM_MENUSELECT ,以進入或結束容器未新增本身的 [說明 ] 功能表上的任何專案。 在輸入時,這表示使用者已流覽至物件功能表,因此容器會設定「物件說明功能表」旗標,並使用該旗標的狀態,將任何 WM_MENUSELECT 、 WM_INITMENUPOPUP 及 WM_COMMAND 訊息轉送至物件視窗。 (結束時,容器會清除旗標,然後處理這些相同的訊息本身。容器應該使用從物件函 IOleInPlaceActiveObejct::GetWindow
式傳回的視窗作為這些訊息的目的地。
如果物件在 OLEMENUGROUPWIDTHS 的第六個元素 中偵測到零,則會根據一般的 OLE Documents 規則繼續進行。 此程式涵蓋參與 [ 說明 ] 功能表合併的容器,以及未合併的容器。
物件在顯示合併功能表列之前呼叫 IOleInPlaceFrame::SetMenu
時,容器會檢查 [說明 ] 功能表是否有 額外的子功能表,以及容器已插入的內容。 如果是,容器會將其 [說明 ] 功能表保留在 合併的功能表列中。 如果 [ 說明 ] 功能表沒有額外的子功能表,容器會從合併的功能表列移除其 [說明 ] 功能表。 此程式涵蓋參與 [ 說明 ] 功能表合併的物件,以及未合併的物件。
最後,當該重新組譯功能表時,物件除了移除其他插入的功能表之外,也會移除插入 的說明功能表。 當容器移除其功能表時,除了已插入的其他功能表之外,還會移除其 [說明 ] 功能表。