Share via


テクニカル ノート 71: MFC IOleCommandTarget の実装

Note

次のテクニカル ノートは、最初にオンライン ドキュメントの一部とされてから更新されていません。 結果として、一部のプロシージャおよびトピックが最新でないか、不正になります。 最新の情報について、オンライン ドキュメントのキーワードで関係のあるトピックを検索することをお勧めします。

IOleCommandTarget インターフェイスを使用すると、オブジェクトとそのコンテナーがコマンドを互いにディスパッチできます。 たとえば、オブジェクトのツール バーには、PrintPrint PreviewSaveNewZoom などのコマンドのボタンが含まれている場合があります。 このようなオブジェクトが IOleCommandTarget をサポートするコンテナーに埋め込まれている場合、オブジェクトはそのボタンを有効にし、ユーザーがそれらをクリックした場合を処理するためのコマンドをコンテナーに転送できます。 埋め込みオブジェクトがそれ自体を印刷する必要があるコンテナーでは、埋め込みオブジェクトの IOleCommandTarget インターフェイスを介してコマンドを送信することで、この要求を行うことができます。

IOleCommandTarget は、クライアントがサーバー上のメソッドを呼び出すために使用するという点でオートメーションに似たインターフェイスです。 ただし、IOleCommandTarget を使用すると、通常負荷が高い IDispatchInvoke メソッドをプログラマが使用する必要がないため、オートメーション インターフェイスを介して呼び出しを行うことに伴うオーバーヘッドが節約されます。

MFC では、IOleCommandTarget インターフェイスは、Active ドキュメント コンテナーがサーバーにコマンドをディスパッチできるようにするために、Active ドキュメント サーバーによって使用されます。 Active ドキュメント サーバー クラス CDocObjectServerItem では、MFC インターフェイス マップ (「テクニカル ノート 38: MFC/OLE IUnknown の実装」を参照) を使用して、IOleCommandTarget インターフェイスを実装します。

IOleCommandTarget は、COleFrameHook クラスにも実装されています。 COleFrameHook は、インプレース編集コンテナーのフレーム ウィンドウ機能を実装する、ドキュメントに未記載の MFC クラスです。 COleFrameHook も、MFC インターフェイス マップを使用して、IOleCommandTarget インターフェイスを実装します。 COleFrameHookIOleCommandTarget の実装は、OLE コマンドを COleDocObjectItem から派生した Active ドキュメント コンテナーに転送します。 これにより、MFC Active ドキュメント コンテナーは、含まれている Active ドキュメント サーバーからメッセージを受信できます。

MFC OLE コマンド マップ

MFC 開発者は、MFC OLE コマンド マップを使用して、IOleCommandTarget を利用できます。 OLE コマンド マップは、コマンド マップを含むクラスのメンバー関数に OLE コマンドをマップするために使用できるため、メッセージ マップに似ています。 これが機能するには、コマンド マップにマクロを配置して、処理するコマンドの OLE コマンド グループ、OLE コマンド、および OLE コマンドの受信時に送信される WM_COMMAND メッセージのコマンド ID を指定します。 MFC には、標準 OLE コマンド用の定義済みマクロも多数用意されています。 もともと Microsoft Office アプリケーションで使用するために設計された標準 OLE コマンドの一覧については、docobj.h 内に定義されている OLECMDID 列挙型を参照してください。

OLE コマンド マップを含む MFC アプリケーションが OLE コマンドを受け取ると、MFC はアプリケーションの OLE コマンド マップ内で、要求されたコマンドのコマンド ID とコマンド グループの検索を試みます。 一致が見つかった場合、要求されたコマンドの ID を含む WM_COMMAND メッセージがコマンド マップを含むアプリケーションにディスパッチされます (以下の説明を ON_OLECMD 参照してください)。このように、アプリケーションにディスパッチされた OLE コマンドは、MFC によってWM_COMMAND メッセージに変換されます。 次に、WM_COMMAND メッセージは、MFC 標準コマンド ルーティング アーキテクチャを使用して、アプリケーションのメッセージ マップを介してルーティングされます。

メッセージ マップとは異なり、MFC OLE コマンド マップは ClassWizard ではサポートされません。 MFC 開発者は、OLE コマンド マップのサポートと OLE コマンド マップのエントリを手動で追加する必要があります。 OLE コマンド マップは、Active ドキュメントがコンテナー内でインプレース アクティブである時点で WM_COMMAND メッセージルーティング チェーン内にある任意のクラス内で MFC Active ドキュメント サーバーに追加できます。 これらのクラスには、CWinAppCViewCDocumentCOleIPFrameWnd から派生したアプリケーションのクラスが含まれます。 Active ドキュメント コンテナーでは、OLE コマンド マップは COleDocObjectItem 派生クラスにのみ追加できます。 また、Active ドキュメント コンテナーでは、WM_COMMAND メッセージは、COleDocObjectItem 派生クラスのメッセージ マップにのみディスパッチされます。

OLE コマンド マップのマクロ

コマンド マップ機能をクラスに追加するには、次のマクロを使用します。

DECLARE_OLECMD_MAP ()

このマクロは、コマンド マップを含むクラスのクラス宣言 (通常はヘッダー ファイル内) に含めます。

BEGIN_OLECMD_MAP(theClass, baseClass)

theClass
コマンド マップを含むクラスの名前。

baseClass
コマンド マップを含むクラスの基底クラスの名前。

このマクロは、コマンド マップの先頭をマークします。 コマンド マップを含むクラスの実装ファイル内で、このマクロを使用します。

END_OLECMD_MAP()

このマクロは、コマンド マップの末尾をマークします。 コマンド マップを含むクラスの実装ファイル内で、このマクロを使用します。 このマクロは、必ず BEGIN_OLECMD_MAP マクロの後に置く必要があります。

ON_OLECMD(pguid, olecmdid, id)

pguid
OLE コマンドのコマンド グループの GUID へのポインター。 このパラメーターは、標準 OLE コマンド グループの場合は NULL です。

olecmdid
呼び出されるコマンドの OLE コマンド ID。

id
この OLE コマンドが呼び出されたときに、コマンド マップを含むアプリケーションに送信される WM_COMMAND メッセージの ID。

処理する OLE コマンドのエントリを追加するには、コマンド マップ内で ON_OLECMD マクロを使用します。 受信された OLE コマンドは、指定された WM_COMMAND メッセージに変換され、標準の MFC コマンドルーティング アーキテクチャを使用してアプリケーションのメッセージ マップを介してルーティングされます。

次の例は、OLECMDID_PRINT OLE コマンドを処理する OLE コマンド処理機能を MFC Active ドキュメント サーバーに追加する方法を示しています。 この例では、AppWizard を使用して、Active ドキュメント サーバーである MFC アプリケーションを生成していることを前提としています。

  1. CView 派生クラスのヘッダー ファイルのクラス宣言に DECLARE_OLECMD_MAP マクロを追加します。

    Note

    CView 派生クラスを使用するのは、これが WM_COMMAND メッセージルーティング チェーン内にある Active ドキュメント サーバーのクラスの 1 つであるためです。

    class CMyServerView : public CView
    {
    protected: // create from serialization only
        CMyServerView();
        DECLARE_DYNCREATE(CMyServerView)
        DECLARE_OLECMD_MAP()
        // . . .
    };
    
  2. CView 派生クラスの実装ファイル内に、BEGIN_OLECMD_MAP と END_OLECMD_MAP マクロを追加します。

    BEGIN_OLECMD_MAP(CMyServerView, CView)
    
    END_OLECMD_MAP()
    
  3. 標準 OLE 印刷コマンドを処理するには、コマンド マップに ON_OLECMD マクロを追加し、標準印刷コマンドの OLE コマンド ID と WM_COMMAND ID の ID_FILE_PRINT を指定します。 ID_FILE_PRINT は、AppWizard によって生成された MFC アプリケーションによって使用される標準印刷コマンド ID です。

    BEGIN_OLECMD_MAP(CMyServerView, CView)
        ON_OLECMD(NULL, OLECMDID_PRINT, ID_FILE_PRINT)
    END_OLECMD_MAP()
    

OLECMDID_PRINT は標準 OLE コマンド ID なので、afxdocob.h 内に定義されている標準 OLE コマンドのマクロの 1 つを ON_OLECMD マクロの代わりに使用できます。 ON_OLECMD_PRINT マクロは、上に示した ON_OLECMD マクロと同じタスクを実行します。

コンテナー アプリケーションがこのサーバーにサーバーの IOleCommandTarget インターフェイスを介して OLECMDID_PRINT コマンドを送信すると、サーバー内で MFC 印刷コマンド ハンドラーが呼び出され、サーバーがアプリケーションを印刷します。 上記の手順で追加した印刷コマンドを呼び出す Active ドキュメント コンテナーのコードは次のようになります。

void CContainerCntrItem::DoOleCmd()
{
    IOleCommandTarget *pCmd = NULL;
    HRESULT hr = E_FAIL;
    OLECMD ocm={OLECMDID_PRINT, 0};

    hr = m_lpObject->QueryInterface(
        IID_IOleCommandTarget,reinterpret_cast<void**>(&pCmd));

    if (FAILED(hr))
        return;

    hr = pCmd->QueryStatus(NULL, 1, &ocm, NULL);

    if (SUCCEEDED(hr) && (ocm.cmdf& OLECMDF_ENABLED))
    {
        //Command is available and enabled so call it
        COleVariant vIn;
        COleVariant vOut;
        hr = pCmd->Exec(NULL, OLECMDID_PRINT,
            OLECMDEXECOPT_DODEFAULT, &vIn, &vOut);
        ASSERT(SUCCEEDED(hr));
    }
    pCmd->Release();
}

関連項目

番号順テクニカル ノート
カテゴリ別テクニカル ノート