原文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 中添加功能的三个对象的一个所需的各个步骤。
的 COccManager::CreateSite 用于创建 COleControlSite 对象。 若要用于 ControlSite 类将下面的方法添加到您 COccManager 类定义:
重写 IOleControlSite 接口的一个典型示例如下:
COleControlContainer 实现一个或多个 ActiveX 控件的容器。此容器对应于一个特定的窗口中承载多个 ActiveX 控件和其他标准控件的容器应用程序。通常,这是一个对话框。作为容器对象 COleControlContainer 实现两个接口: IOleInPlaceFrame 和 IOleContainer。
对于宿主控件容器对象中的每个控件没有相应的 MFC 控件站点对象。此控件站点对象由 COleControlSite 实现。为宿主的 ActiveX 控件在一对一直接的站点对象在 COleControlSite 实现多个接口: IOleClientSite,IOleInPlaceSite,IOleControlSite,IPropertyNotifySink,IBoundObjectSite,INotifyDBEvents。COleControlSite 还实现两个 IDispatch 接口,一个用于环境属性,另一种为事件接收器的控件。
本文提供了重写这些更改,或在接口级别 COleControlContainer 或 COleControlSite 中添加功能的三个对象的一个所需的各个步骤。
重写 COleControlContainer 的步骤
- 创建从 COleControlContainer 派生的类。构造函数需要直接,调用 COleControlContainer 构造函数没有默认 COleControlContainer 构造函数:
CMyOleControlContainer::CMyOleControlContainer(CWnd* pWnd) : COleControlContainer(pWnd) { }
- 创建从 COccManager 派生的类。添加一个空的构造函数和一个空的虚拟析构函数。
- 重写 COccManager::CreateContainer 函数创建并返回新 COleControlContainer 派生类的新实例。您可以执行此操作通过以下方法向 COccManager 类定义:
virtual COleControlContainer* CreateContainer(CWnd* pWnd) { // Advanced control container applications may want to override. return new CMyOleControlContainer(pWnd); }
- 您的要求 AfxEnableControlContainer (可能在 CYourApp::InitInstance) 对其进行修改以在 COccManager 派生类的实例中传递:
CMyOccManager theManager; // ... BOOL CMfcaxscrvbApp::InitInstance() { // Initialize OLE libraries if (!AfxOleInit()) // ... AfxEnableControlContainer(&theManager);
- 将 Occimpl.h 标头文件包括在您 CMyOccManager CMyOccManager 标头文件之前的实现文件。您可能需要进行直接引用中 # 包含语句,因为 Occimpl.h SRC VC/MFC 目录中。
- 在之前在 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
- 按照标准过程重写中 CMyOleControlContainer 类的接口。有关如何执行此操作的详细信息单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
141277下面是重写 IOleInPlaceFrame 接口的一个典型示例:(http://support.microsoft.com/kb/141277/ )如何重写 MFC 应用程序中的接口
// 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) { }
virtual COleControlSite* CreateSite(COleControlContainer* pCtrlCont) { // advanced control container override return new CMyOleControlSite(pCtrlCont); }
// 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.