Visual C++ を使用して MFC アプリケーションのインターフェイスをオーバーライドする方法

この記事は、以前は次の ID で公開されていました: JP141277
この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
: Microsoft Visual C++ .NET (2002) は、.NET Framework によって提供されるマネージ コード モデルとアンマネージ ネイティブ Windows コード モデルの両方に対応していました。この資料の情報は、Visual C++ のアンマネージ コードのみに適用されます。

: Microsoft Visual C++ 2005 は、.NET Framework によって提供されるマネージ コード モデルとアンマネージ ネイティブ Windows コード モデルの両方に対応しています。
概要
MFC アプリケーションでは、追加のインターフェイスを提供できるだけでなく、クラスの既存のインターフェイスをオーバーライドすることもできます。この場合、インターフェイスのオーバーライドは実質上インターフェイスの置換と同じ意味です。この資料では、サンプルとして、元のインターフェイスのインプリメンテーションを保持したままクラスのインターフェイスをオーバーライドする例を紹介します。これによって元のインプリメンテーションの機能を、新しいインターフェイスに代行させることができます。

この資料では、特殊なケースである IDispatch インプリメンテーションのオーバーライドについては扱いません。MFC の IDispatch をオーバーライドする方法の関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
140616 MFC IDispatch 実装の置換
詳細
次の手順では、コントロール ウィザードによって生成される、デフォルトの OLE コントロールに対する IOleObject インプリメンテーションのオーバーライドを実行します。

  1. コントロールに IOleObject インプリメンテーションの宣言を追加するには、COleControl から派生するクラスのヘッダー ファイルに、次のコードを追加します。
          // Interface Maps      protected:           // IOleObject           BEGIN_INTERFACE_PART(MyOleObject, IOleObject)               INIT_INTERFACE_PART(CIOleOverCtrl, MyOleObject)               STDMETHOD(SetClientSite)(LPOLECLIENTSITE);               STDMETHOD(GetClientSite)(LPOLECLIENTSITE*);               STDMETHOD(SetHostNames)(LPCOLESTR, LPCOLESTR);               STDMETHOD(Close)(DWORD);               STDMETHOD(SetMoniker)(DWORD, LPMONIKER);               STDMETHOD(GetMoniker)(DWORD, DWORD, LPMONIKER*);               STDMETHOD(InitFromData)(LPDATAOBJECT, BOOL, DWORD);               STDMETHOD(GetClipboardData)(DWORD, LPDATAOBJECT*);               STDMETHOD(DoVerb)(LONG, LPMSG, LPOLECLIENTSITE, LONG, HWND,                       LPCRECT);               STDMETHOD(EnumVerbs)(IEnumOLEVERB**);               STDMETHOD(Update)();               STDMETHOD(IsUpToDate)();               STDMETHOD(GetUserClassID)(CLSID*);               STDMETHOD(GetUserType)(DWORD, LPOLESTR*);               STDMETHOD(SetExtent)(DWORD, LPSIZEL);               STDMETHOD(GetExtent)(DWORD, LPSIZEL);               STDMETHOD(Advise)(LPADVISESINK, LPDWORD);               STDMETHOD(Unadvise)(DWORD);               STDMETHOD(EnumAdvise)(LPENUMSTATDATA*);               STDMETHOD(GetMiscStatus)(DWORD, LPDWORD);               STDMETHOD(SetColorScheme)(LPLOGPALETTE);           END_INTERFACE_PART(MyOleObject)      DECLARE_INTERFACE_MAP();						
    このコードによって、入れ子になった XMyOleObject クラスがコントロール クラスに追加されます。これらのマクロには IUnknown などのインターフェイス メソッドが宣言されています。そのため、IUnknown メソッドもインプリメントする必要があります。
  2. INTERFACE_PART マクロをコントロール用のインプリメンテーション ファイルに追加することで、IOleObject インターフェイスをコントロール用のインターフェイス マップに追加します。
          BEGIN_INTERFACE_MAP(CIOleOverCtrl, COleControl)         INTERFACE_PART(CIOleOverCtrl, IID_IOleObject, MyOleObject)      END_INTERFACE_MAP()						
    CIOleOverCtrl を、使用中のコントロールの名前に置換し、次に MyOleObject を、IOleObject をサポートする入れ子になったクラスに割り当てた名前に置換します。
  3. 宣言したインターフェイス メソッドをインプリメントします。コントロール用のインプリメンテーション ファイルに、次のコードを追加します。
          STDMETHODIMP_(ULONG) CIOleOverCtrl::XMyOleObject::AddRef()      {          METHOD_MANAGE_STATE(CIOleOverCtrl, MyOleObject)          ASSERT_VALID(pThis);          return pThis->m_xOleObject.AddRef();      }      STDMETHODIMP_(ULONG) CIOleOverCtrl::XMyOleObject::Release()      {          METHOD_MANAGE_STATE(CIOleOverCtrl, MyOleObject)          ASSERT_VALID(pThis);          return pThis->m_xOleObject.Release ();      }      STDMETHODIMP CIOleOverCtrl::XMyOleObject::QueryInterface(          REFIID iid, LPVOID far* ppvObj)      {          METHOD_MANAGE_STATE(CIOleOverCtrl, MyOleObject)          ASSERT_VALID(pThis);          return pThis->m_xOleObject.QueryInterface ( iid,  ppvObj);      }      STDMETHODIMP      CIOleOverCtrl::XMyOleObject::SetClientSite(LPOLECLIENTSITE      pClientSite)      {          METHOD_MANAGE_STATE(CIOleOverCtrl, MyOleObject)             ASSERT_VALID(pThis);          return pThis->m_xOleObject.SetClientSite ( pClientSite );      }      ...
メソッドの残りの部分も同じパターンにします。CIOleOverCtrl にはコントロールの名前を、XMyOleObject には IOleObject をサポートする入れ子になったクラスの名前を使用します。そしてサポートする IOleObject インターフェイスから "I" を取り除き、代わりに "m_x" を追加することで m_xMyOleObject を作ります。

これらのメソッドの機能は単に、呼び出しを元の IOleObject インプリメンテーションに引き渡すことにあるので注意します。ただし、これは要件ではありません。これらのメソッドに別の機能を追加して元のインプリメンテーションに代理で機能を実行させることもできますが、まったく代理を行わせないこともできます。
関連情報
『MFC テクニカル ノート』の「38」および「39」を参照してください。
プロパティ

文書番号:141277 - 最終更新日: 03/01/2014 07:17:08 - リビジョン: 3.0

  • Microsoft Foundation Class Library 4.2
  • kbnosurvey kbarchive kbhowto kbarchitecture kbctrl KB141277
フィードバック