[ヘルプ] メニューのマージ
オブジェクトがコンテナー内でアクティブな場合、OLE ドキュメントのメニュー マージ プロトコルにより、オブジェクトが [ヘルプ] メニューを完全に消去できます。 その結果、ユーザーがオブジェクトを非アクティブ化しない限り、コンテナーのヘルプ トピックは使用できません。 アクティブなドキュメントが含まれたアーキテクチャでは、コンテナーとアクティブなドキュメントの両方がメニューを共有できるように、インプレース メニュー マージのルールに基づいて拡張します。 新しいルールは、どのコンポーネントがメニューのどの部分を所有し、共有メニューがどのように構築されるのかについての追加の規則です。
新しい規則は単純です。 アクティブなドキュメントの [ヘルプ] メニューでは、次のように 2 つのトップ レベルのメニュー項目がまとめられています。
Help
Container Help >
Object Help >
たとえば、Office Binder の Word セクションがアクティブな場合、[ヘルプ] メニューは次のように表示されます。
Help
Binder Help >
Word Help >
どちらのメニュー項目もカスケード メニューであり、その下に、コンテナーとオブジェクトに固有の追加のメニュー項目が表示されます。 ここに表示される項目は、関係するコンテナーとオブジェクトによって異なります。
このマージされた [ヘルプ] メニューを作成するために、アクティブなドキュメントが含まれたアーキテクチャによって通常の OLE ドキュメント プロシージャが変更されます。 OLE ドキュメントに応じて、マーチされたメニュー バーには、[ファイル]、[編集]、[コンテナー]、[オブジェクト]、[ウィンドウ]、[ヘルプ] という 6 つのメニュー グループをこの順番で含めることができます。 各グループには、0 個以上のメニューを指定できます。 [ファイル]、[コンテナー]、および [ウィンドウ] グループはコンテナーに属し、[編集]、[オブジェクト]、および [ヘルプ] グループはオブジェクトに属します。 オブジェクトがメニューのマージを実行する場合は、空白のメニュー バーが作成され、コンテナーに渡されます。 次に、コンテナーは IOleInPlaceFrame::InsertMenus を呼び出して、コンテナーのメニューを挿入します。 オブジェクトは、6 つの LONG 値 (OLEMENUGROUPWIDTHS) の配列である構造体も渡します。 メニューを挿入した後、コンテナーは各グループに追加したメニューの数をマークしてから、返します。 次に、オブジェクトによってメニューが挿入されます。各コンテナー グループ内のメニューの数に注意してください。 最後に、オブジェクトは、マージされたメニュー バーと配列 (各グループのメニュー数を含む) を OLE に渡します。これにより、不透明な「メニュー記述子」ハンドルが返されます。 後で、IOleInPlaceFrame::SetMenu を介して、オブジェクトはそのハンドルとマージされたメニュー バーをコンテナーに渡します。 この時点で、コンテナーはマージされたメニュー バーを表示し、ハンドルを OLE に渡して、OLE がメニュー メッセージを適切にディスパッチできるようにします。
変更されたアクティブなドキュメント プロシージャでは、オブジェクトは最初に OLEMENUGROUPWIDTHS 要素をゼロに初期化してから、コンテナーに渡す必要があります。 次に、コンテナーは 1 つの例外を除いて通常のメニュー挿入を実行します。コンテナーは、最後の項目として [ヘルプ] メニューを挿入し、OLEMENUGROUPWIDTHS 配列の最後 (6 番目) のエントリ (つまり、オブジェクトのヘルプ グループに属する width[5]) に値 1 を格納します。 この [ヘルプ] メニューには、前に説明したように、サブメニューである「コンテナー ヘルプ>」のカスケード メニューである項目が 1 つのみ含まれます。
その後、オブジェクトは通常のメニュー挿入コードを実行しますが、例外として、その [ヘルプ] メニューを挿入する前に、OLEMENUGROUPWIDTHS 配列の 6 番目のエントリがチェックされます。 値が 1 で、最後のメニューの名前が [ヘルプ] (または適切なローカライズされた文字列) の場合、オブジェクトは [ヘルプ] メニューをコンテナーの [ヘルプ] メニューのサブメニューとして挿入します。
次に、オブジェクトは 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 を呼び出すと、コンテナーは [ヘルプ] メニューに、コンテナーが挿入したものに加えて追加のサブメニューがあるかどうかをチェックします。 ある場合、コンテナーは [ヘルプ] メニューをマージされたメニュー バーに残します。 [ヘルプ] メニューに追加のサブメニューがない場合、コンテナーはその [ヘルプ] メニューをマージされたメニュー バーから削除します。 この手順では、[ヘルプ] メニューのマージに参加するオブジェクトと、参加しないオブジェクトについて説明します。
最後に、メニューを逆アセンブルする際に、オブジェクトは、挿入された他のメニューを削除するだけではなく、挿入された [ヘルプ] メニューも削除します。 コンテナーがメニューを削除すると、挿入された他のメニューに加えて、その [ヘルプ] メニューも削除されます。