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

来源:互联网 发布:手机淘宝联盟怎么领券 编辑:程序博客网 时间:2024/05/23 21:51

 http://support.microsoft.com/kb/196835

 

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  (http://support.microsoft.com/kb/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.

 

 
原创粉丝点击