次の方法で共有


TN071: MFC IOleCommandTarget の実装

次のテクニカル ノートは、最初にオンライン ドキュメントに含まれてから更新されていません。 その結果、一部の手順やトピックが古くなっているか、正しくない可能性があります。 最新情報については、オンライン ドキュメント インデックスで関心のあるトピックを検索することをお勧めします。

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

IOleCommandTarget は、サーバー上のメソッドを呼び出すためにクライアントによって使用されるという点でオートメーションに似たインターフェイスです。 ただし、 IOleCommandTarget を使用すると、プログラマは一般的に高価な Invoke メソッドを使用する必要がないため、オートメーション インターフェイス経由で呼び出しを行うオーバーヘッド IDispatch

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

IOleCommandTarget は、 COleFrameHook クラスにも実装されます。 COleFrameHook は、インプレース編集コンテナーのフレーム ウィンドウ機能を実装する文書化されていない MFC クラスです。 COleFrameHook また、MFC インターフェイス マップを使用して、 IOleCommandTarget インターフェイスを実装します。 COleFrameHook IOleCommandTargetの実装により、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 とコマンド グループを検索しようとします。 一致が見つかった場合、WM_COMMAND メッセージは、要求されたコマンドの ID を持つコマンド マップを含むアプリケーションにディスパッチされます。 (以下の ON_OLECMD の説明を参照してください)。このように、アプリケーションにディスパッチされた OLE コマンドは、MFC によってWM_COMMAND メッセージに変換されます。 その後、WM_COMMAND メッセージは、MFC 標準 コマンド ルーティング アーキテクチャを使用して、アプリケーションのメッセージ マップを介してルーティングされます。

メッセージ マップとは異なり、MFC OLE コマンド マップは ClassWizard ではサポートされていません。 MFC 開発者は、OLE コマンド マップのサポートと OLE コマンド マップ エントリを手動で追加する必要があります。 OLE コマンド マップは、アクティブ ドキュメントがコンテナー内でインプレース アクティブになっている時点で、WM_COMMAND メッセージ ルーティング チェーン内にある任意のクラスの MFC Active ドキュメント サーバーに追加できます。 これらのクラスには、CWinApp、CViewCDocument、および COleIPFrameWnd から派生したアプリケーションのクラスが含まれます。 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。

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

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

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

    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 印刷コマンドを処理するには、標準の印刷コマンドの OLE コマンド ID と WM_COMMAND ID のID_FILE_PRINTを指定する ON_OLECMD マクロをコマンド マップに追加します。 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 印刷コマンド ハンドラーがサーバーで呼び出され、サーバーによってアプリケーションが印刷されます。 上記の手順で追加した print コマンドを呼び出す 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();
}

こちらも参照ください

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