如何重写的 MFC 控件容器接口方法,在 Visual c + + 中的几个默认行为

原文http://support.microsoft.com/kb/196835/zh-cn

 

MFC 控件容器支持涉及三个主类: COccManager,COleControlContainer,和 COleControlSite。COccManager 是一个 MFC 进程中的所有控件容器的主控制器,并负责处理出 COleControlSite 和 COleControlContainer 对象的指针。COccManager 还具有一个 IsDialogMessage 方法,实现消息处理功能所需的 ActiveX 控件容器。

COleControlContainer 实现一个或多个 ActiveX 控件的容器。此容器对应于一个特定的窗口中承载多个 ActiveX 控件和其他标准控件的容器应用程序。通常,这是一个对话框。作为容器对象 COleControlContainer 实现两个接口: IOleInPlaceFrame 和 IOleContainer。

对于宿主控件容器对象中的每个控件没有相应的 MFC 控件站点对象。此控件站点对象由 COleControlSite 实现。为宿主的 ActiveX 控件在一对一直接的站点对象在 COleControlSite 实现多个接口: IOleClientSite,IOleInPlaceSite,IOleControlSite,IPropertyNotifySink,IBoundObjectSite,INotifyDBEvents。COleControlSite 还实现两个 IDispatch 接口,一个用于环境属性,另一种为事件接收器的控件。

本文提供了重写这些更改,或在接口级别 COleControlContainer 或 COleControlSite 中添加功能的三个对象的一个所需的各个步骤。

重写 COleControlContainer 的步骤

  1. 创建从 COleControlContainer 派生的类。构造函数需要直接,调用 COleControlContainer 构造函数没有默认 COleControlContainer 构造函数:
          CMyOleControlContainer::CMyOleControlContainer(CWnd* pWnd) :
             COleControlContainer(pWnd)
          {
          }
    					
  2. 创建从 COccManager 派生的类。添加一个空的构造函数和一个空的虚拟析构函数。
  3. 重写 COccManager::CreateContainer 函数创建并返回新 COleControlContainer 派生类的新实例。您可以执行此操作通过以下方法向 COccManager 类定义:
          virtual COleControlContainer* CreateContainer(CWnd* pWnd)
          {
             // Advanced control container applications may want to override.
             return new CMyOleControlContainer(pWnd);
          }
    					
  4. 您的要求 AfxEnableControlContainer (可能在 CYourApp::InitInstance) 对其进行修改以在 COccManager 派生类的实例中传递:
          CMyOccManager theManager;
    
          // ...
    
          BOOL CMfcaxscrvbApp::InitInstance()
          {
             // Initialize OLE libraries
             if (!AfxOleInit())
             // ...
             AfxEnableControlContainer(&theManager);
    					
    : 对于一个 CHtmlView 派生类及其 Create 函数调用 AfxEnableControlContainer() 导致它重写我们最初的自定义 COccManager 类。若要不必此问题,您需要重写 CHtmlView::Create、 将所有的代码复制到调用 AfxEnableC ntrolContainer() 减去您重写 Create 函数。请记住 NOT,因为原始的实现未调用基类的创建方法。

  5. 将 Occimpl.h 标头文件包括在您 CMyOccManager CMyOccManager 标头文件之前的实现文件。您可能需要进行直接引用中 # 包含语句,因为 Occimpl.h SRC VC/MFC 目录中。
  6. 在之前在 CMyOleControlContainer CMyOleControlContainer 实现文件中包含 Occimpl.h 头文件的头文件。使用该 AFX_DATA 定义为了确保 Occimpl.h 中定义的类导入数据:
          #undef AFX_DATA
          #define AFX_DATA AFX_DATA_IMPORT
          #include "c:\program files\devstudio\vc\mfc\src\occimpl.h"
          #undef AFX_DATA
          #define AFX_DATA AFX_DATA_EXPORT
    					
  7. 按照标准过程重写中 CMyOleControlContainer 类的接口。有关如何执行此操作的详细信息单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
    141277 如何重写 MFC 应用程序中的接口
    下面是重写 IOleInPlaceFrame 接口的一个典型示例:
          // Inside header definition in .h.
          class CMyOleControlContainer : public COleControlContainer
          {
          // ...
             // Interface maps.
             BEGIN_INTERFACE_PART(MyOleIPFrame, IOleInPlaceFrame)
                INIT_INTERFACE_PART(CMyOleControlContainer, MyOleIPFrame)
                STDMETHOD(GetWindow)(HWND*);
                STDMETHOD(ContextSensitiveHelp)(BOOL);
                STDMETHOD(GetBorder)(LPRECT);
                STDMETHOD(RequestBorderSpace)(LPCBORDERWIDTHS);
                STDMETHOD(SetBorderSpace)(LPCBORDERWIDTHS);
                STDMETHOD(SetActiveObject)(LPOLEINPLACEACTIVEOBJECT,
                                           LPCOLESTR);
                STDMETHOD(InsertMenus)(HMENU, LPOLEMENUGROUPWIDTHS);
                STDMETHOD(SetMenu)(HMENU, HOLEMENU, HWND);
                STDMETHOD(RemoveMenus)(HMENU);
                STDMETHOD(SetStatusText)(LPCOLESTR);
                STDMETHOD(EnableModeless)(BOOL);
                STDMETHOD(TranslateAccelerator)(LPMSG, WORD);
             END_INTERFACE_PART(MyOleIPFrame)
    
             DECLARE_INTERFACE_MAP()
          };
    
          // Inside implementation file .cpp:
    
          BEGIN_INTERFACE_MAP(CMyOleControlContainer, COleControlContainer)
             INTERFACE_PART(CMyOleControlContainer, IID_IOleInPlaceFrame,
                            MyOleIPFrame)
          END_INTERFACE_MAP()
    
          STDMETHODIMP CMyOleControlContainer::XMyOleIPFrame::QueryInterface(
             REFIID iid, LPVOID* ppvObj)
          {
             METHOD_PROLOGUE_EX_(CMyOleControlContainer, MyOleIPFrame)
             return (HRESULT)pThis->InternalQueryInterface(&iid, ppvObj);
          }
    
          STDMETHODIMP_(ULONG) CMyOleControlContainer::XMyOleIPFrame::AddRef()
          {
             METHOD_PROLOGUE_EX_(CMyOleControlContainer, MyOleIPFrame)
             return (ULONG)pThis->InternalAddRef();
          }
    
          // ...
          // Cut and paste all of this code from the MFC source in Occimpl.h
          // and change all references to COleControlContainer to reference
          // your class. Then, modify methods as desired. For example, here is
          // a customized enablemodeless call:
    
          STDMETHODIMP
             CMyOleControlContainer::XMyOleIPFrame::EnableModeless(BOOL f)
          {
             METHOD_PROLOGUE_EX(CMyOleControlContainer, MyOleIPFrame)
    
             CWinApp* pApp = AfxGetApp();
             if (!pApp)
                return E_FAIL;
    
             pApp->EnableModeless(f);
             return S_OK;
          }
    					

重写 COleControlSite 的步骤

重写 COleControlSite 的步骤相同的 COleControlContainer,COleControlSite 替换为 COleControlContainer,在适当的位置。请遵循某些相关的代码段:
   CMyOleControlSite::CMyOleControlSite(COleControlContainer* pCtrlCont) :
      COleControlSite(pCtrlCont)
   {

   }
				
的 COccManager::CreateSite 用于创建 COleControlSite 对象。 若要用于 ControlSite 类将下面的方法添加到您 COccManager 类定义:
   virtual COleControlSite* CreateSite(COleControlContainer* pCtrlCont)
   {
      // advanced control container override
      return new CMyOleControlSite(pCtrlCont);
   }
				
重写 IOleControlSite 接口的一个典型示例如下:
   // Inside header definition in .h:
   class CMyOleControlSite : public COleControlSite
   {
   // ...
      // Interface maps.
      BEGIN_INTERFACE_PART(MyOleControlSite, IOleControlSite)
         INIT_INTERFACE_PART(CMyOleControlSite, MyOleControlSite)
         STDMETHOD(OnControlInfoChanged)();
         STDMETHOD(LockInPlaceActive)(BOOL fLock);
         STDMETHOD(GetExtendedControl)(LPDISPATCH* ppDisp);
         STDMETHOD(TransformCoords)(POINTL* lpptlHimetric,
            POINTF* lpptfContainer, DWORD flags);
         STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, DWORD grfModifiers);
         STDMETHOD(OnFocus)(BOOL fGotFocus);
         STDMETHOD(ShowPropertyFrame)();
      END_INTERFACE_PART(MyOleControlSite)

      DECLARE_INTERFACE_MAP()
   };

   // Inside implementation file .cpp:

      BEGIN_INTERFACE_MAP(CMyOleControlSite, CMyOleControlSite)
         INTERFACE_PART(CMyOleControlSite, IID_IOleControlSite,
                        MyOleControlSite)
      END_INTERFACE_MAP()

   STDMETHODIMP_(ULONG) CMyOleControlSite::XMyOleControlSite::AddRef()
   {
      METHOD_PROLOGUE_EX_(CMyOleControlSite, OleControlSite)
      return (ULONG)pThis->InternalAddRef();
   }

   STDMETHODIMP_(ULONG) CMyOleControlSite::XMyOleControlSite::Release()
   {
      METHOD_PROLOGUE_EX_(CMyOleControlSite, OleControlSite)
      return (ULONG)pThis->InternalRelease();
   }

   // ...
   // Cut and paste all of this code from the MFC source in Occimpl.h
   // and change all references to COleControlSite to reference your
   // class. Then, modify methods as desired.
				
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值