オブジェクトがコンテナー内でアクティブな場合、OLE ドキュメントのメニューマージ プロトコルにより、オブジェクトは ヘルプ メニューを完全に制御できます。 その結果、ユーザーがオブジェクトを非アクティブ化しない限り、コンテナーのヘルプ トピックは使用できません。 アクティブドキュメントコンテインメントアーキテクチャは、メニュー結合ルールを拡張して、コンテナーとアクティブドキュメントの両方がメニューを共有できるようにします。 新しいルールは、どのコンポーネントがメニューのどの部分を所有しているか、および共有メニューがどのように構築されるかについての単なる追加規則です。
新しい規則は単純です。 作業中のドキュメントでは、[ ヘルプ ] メニューには、次の 2 つの最上位メニュー項目があります。
Help
Container Help >
Object Help >
たとえば、Office Binder で Word セクションがアクティブな場合、[ ヘルプ ] メニューは次のように表示されます。
Help
Binder Help >
Word Help >
どちらのメニュー項目もカスケード メニューであり、コンテナーとオブジェクトに固有の追加のメニュー項目がユーザーに提供されます。 ここに表示される項目は、関係するコンテナーとオブジェクトによって異なります。
この結合された ヘルプ メニューを作成するために、作業中のドキュメントコンテインメント アーキテクチャによって、通常の OLE ドキュメント プロシージャが変更されます。 OLE ドキュメントによると、結合されたメニュー バーには、ファイル、編集、コンテナー、オブジェクト、ウィンドウ、ヘルプの 6 つのメニュー グループをその順序で含めることができます。 各グループには、0 個以上のメニューを含めることができます。 ファイル、コンテナー、ウィンドウのグループはコンテナーに属し、グループ Edit、Object、および Help はオブジェクトに属します。 オブジェクトがメニューのマージを実行する場合、空のメニュー バーが作成され、コンテナーに渡されます。 コンテナーは、 IOleInPlaceFrame::InsertMenusを呼び出してメニューを挿入します。 オブジェクトは、6 つの LONG 値 (OLEMENUGROUPWIDTHS) の配列である構造体も渡します。 メニューを挿入した後、コンテナーは各グループに追加されたメニューの数をマークし、返します。 次に、オブジェクトはそのメニューを挿入し、各コンテナー グループ内のメニューの数に注意します。 最後に、オブジェクトは結合されたメニュー バーと配列 (各グループ内のメニューの数を含む) を OLE に渡し、不透明な "メニュー記述子" ハンドルを返します。 その後、オブジェクトはそのハンドルとマージされたメニュー バーを、 IOleInPlaceFrame::SetMenu経由でコンテナーに渡します。 この時点で、コンテナーは結合されたメニュー バーを表示し、OLE にハンドルを渡して、OLE がメニュー メッセージを適切にディスパッチできるようにします。
変更された作業中のドキュメント プロシージャでは、オブジェクトをコンテナーに渡す前に、 OLEMENUGROUPWIDTHS 要素を最初に 0 に初期化する必要があります。 次に、コンテナーは通常のメニュー挿入を実行しますが、1 つの例外があります。コンテナーは 、ヘルプ メニューを最後の項目として挿入し、 OLEMENUGROUPWIDTHS 配列の最後 (6 番目) のエントリ (つまり、オブジェクトのヘルプ グループに属する width[5]) に値 1 を格納します。 この ヘルプ メニューには、前に説明したようにサブメニューである 1 つの項目 、"コンテナー ヘルプ>" カスケード メニューのみが表示されます。
オブジェクトは、その ヘルプ メニューを挿入する前に OLEMENUGROUPWIDTHS 配列の 6 番目のエントリをチェックすることを除き、通常のメニュー挿入コードを実行します。 値が 1 で、最後のメニューの名前が Help (または適切なローカライズされた文字列) の場合、オブジェクトはその ヘルプ メニューをコンテナーの ヘルプ メニューのサブメニューとして挿入します。
次に、 OLEMENUGROUPWIDTHS の 6 番目の要素を 0 に設定し、5 番目の要素を 1 ずつインクリメントします。 これにより、 OLE はヘルプ メニューがコンテナーに属し、そのメニュー (およびそのサブメニュー) に対応するメニュー メッセージをコンテナーにルーティングする必要があることを知らせます。 その後、ヘルプ メニューのオブジェクトの部分に属するWM_INITMENUPOPUP、WM_SELECT、WM_COMMAND、およびその他のメニュー関連メッセージを転送するのはコンテナーの責任です。 これを行うには、 WM_INITMENU を使用して、ユーザーがオブジェクトの ヘルプ メニューに移動したかどうかをコンテナーに通知するフラグをクリアします。 その後、コンテナーは、コンテナー自体が追加しなかったヘルプメニュー内の項目への出入りを検出するためにWM_MENUSELECTを監視します。 エントリ時には、ユーザーがオブジェクト メニューに移動したことを意味するため、コンテナーは "in object Help menu" フラグを設定 し、そのフラグの状態を使用して、WM_MENUSELECT、 WM_INITMENUPOPUP、 およびWM_COMMAND メッセージを少なくともオブジェクト ウィンドウに転送します。 (終了時に、コンテナーはフラグをクリアし、これらの同じメッセージ自体を処理します)。コンテナーでは、オブジェクトの IOleInPlaceActiveObejct::GetWindow 関数から返されたウィンドウを、これらのメッセージの宛先として使用する必要があります。
オブジェクトが OLEMENUGROUPWIDTHS の 6 番目の要素で 0 を検出すると、通常の OLE ドキュメントルールに従って続行されます。 この手順では、 ヘルプ メニューのマージに参加するコンテナーと、結合しないコンテナーについて説明します。
オブジェクトが IOleInPlaceFrame::SetMenuを呼び出すと、マージされたメニュー バーを表示する前に、コンテナーは、コンテナーが挿入した内容に加えて、 ヘルプ メニューに追加のサブメニューがあるかどうかを確認します。 その場合、コンテナーは、マージされたメニュー バーに ヘルプ メニューを残します。 [ヘルプ] メニューに追加のサブメニューがない場合、コンテナーは結合されたメニュー バーからヘルプ メニューを削除します。 この手順では、 ヘルプ メニューの結合に含まれるオブジェクトと、結合しないオブジェクトについて説明します。
最後に、メニューを逆アセンブルするとき、オブジェクトは、挿入された 他のメニュー を削除するだけでなく、挿入されたヘルプ メニューを削除します。 コンテナーがメニューを削除すると、挿入した他のメニューに加えて 、そのヘルプ メニューも削除されます。