C++ MFC WebBrowser 探索(三)

其源文件如下:

#include "StdAfx.h"  
#include "SiteCtrl.h"  
      
#include"Custom.h"  
BEGIN_INTERFACE_MAP(SiteCtrl,COleControlSite)  
    INTERFACE_PART(SiteCtrl,IID_IDocHostUIHandler,DocHostUIHandler)  
END_INTERFACE_MAP()  
      
          
ULONG SiteCtrl::XDocHostUIHandler::AddRef()  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return pThis->ExternalAddRef();  
}  
      
      
ULONG SiteCtrl::XDocHostUIHandler::Release()  
{                              
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return pThis->ExternalRelease();  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::QueryInterface(REFIID riid, void** ppvObj)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&riid, ppvObj);  
    return hr;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::GetHostInfo(DOCHOSTUIINFO* pInfo)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    pInfo->dwFlags = DOCHOSTUIFLAG_NO3DBORDER;  
    pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;  
    return S_OK;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::ShowUI(  
                DWORD dwID,  
                IOleInPlaceActiveObject* /*pActiveObject*/,  
                IOleCommandTarget* pCommandTarget,  
                IOleInPlaceFrame* /*pFrame*/,  
                IOleInPlaceUIWindow* /*pDoc*/)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return S_OK;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::HideUI(void)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return S_OK;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::UpdateUI(void)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return S_OK;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::EnableModeless(BOOL /*fEnable*/)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return E_NOTIMPL;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::OnDocWindowActivate(BOOL /*fActivate*/)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return E_NOTIMPL;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::OnFrameWindowActivate(BOOL /*fActivate*/)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return E_NOTIMPL;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::ResizeBorder(  
                LPCRECT /*prcBorder*/,  
                IOleInPlaceUIWindow* /*pUIWindow*/,  
                BOOL /*fRameWindow*/)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return E_NOTIMPL;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::ShowContextMenu(  
                DWORD /*dwID*/,  
                POINT* pptPosition,  
                IUnknown* /*pCommandTarget*/,  
                IDispatch* /*pDispatchObjectHit*/)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return S_OK; // We've shown our own context menu. MSHTML.DLL will no longer try to show its own.  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::TranslateAccelerator(  
            /* [in] */ LPMSG lpMsg,  
            /* [in] */ const GUID __RPC_FAR* pguidCmdGroup,  
            /* [in] */ DWORD nCmdID)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
          
    //disable F5  
    if(lpMsg->message==WM_KEYDOWN && GetAsyncKeyState(VK_F5)<0)  
    {  
        return S_OK;  
    }  
          
    if(GetKeyState(VK_CONTROL) & 0x8000)  
    {  
        // disable ctrl + O  
        if(lpMsg->message==WM_KEYDOWN && GetAsyncKeyState(0x4F)<0)  
        {  
            return S_OK;  
        }  
        //disable ctrl + p  
        if(lpMsg->message==WM_KEYDOWN && GetAsyncKeyState(0x50)<0)  
        {  
            return S_OK;  
        }  
        //disable ctrl + N  
        if(lpMsg->message==WM_KEYDOWN && GetAsyncKeyState(0x4E)<0)  
        {  
            return S_OK;  
        }  
    }  
          
    //disable back space  
//  if(lpMsg->wParam == VK_BACK)  
//  {  
//      return S_OK;  
//  }  
          
    return S_FALSE;  
}  
      
HRESULT SiteCtrl::XDocHostUIHandler::GetOptionKeyPath(BSTR* pbstrKey, DWORD)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return E_NOTIMPL;  
}  
      
STDMETHODIMP SiteCtrl::XDocHostUIHandler::GetDropTarget(  
            /* [in] */ IDropTarget __RPC_FAR* pDropTarget,  
            /* [out] */ IDropTarget __RPC_FAR*__RPC_FAR* ppDropTarget)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return E_NOTIMPL;  
}  
      
STDMETHODIMP SiteCtrl::XDocHostUIHandler::GetExternal(   
            /* [out] */ IDispatch __RPC_FAR*__RPC_FAR* ppDispatch)  
{  
    // return the IDispatch we have for extending the object Model  
    *ppDispatch=theApp.pImp;  
    return S_OK;  
}  
              
STDMETHODIMP SiteCtrl::XDocHostUIHandler::TranslateUrl(  
            /* [in] */ DWORD dwTranslate,  
            /* [in] */ OLECHAR __RPC_FAR *pchURLIn,  
            /* [out] */ OLECHAR __RPC_FAR*__RPC_FAR* ppchURLOut)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return E_NOTIMPL;  
}  
              
STDMETHODIMP SiteCtrl::XDocHostUIHandler::FilterDataObject(   
            /* [in] */ IDataObject __RPC_FAR* pDO,  
            /* [out] */ IDataObject __RPC_FAR*__RPC_FAR* ppDORet)  
{  
    METHOD_PROLOGUE(SiteCtrl, DocHostUIHandler)  
    return E_NOTIMPL;  
}  
      
SiteCtrl::~SiteCtrl(void)  
{  
}

获得IDispatch接口,在这里我们只实现GetExternal,获得了IDispatch接口,如函数中theApp是应用程序的句柄,而pImp则是实现IDispatch类的指针。
接下来是实现COccManager接口,方便我们进行实现AfxEnableControlContainer函数的参数:

class  CSiteManager : public COccManager  
{  
public:  
    CSiteManager(){}  
    COleControlSite* CreateSite(COleControlContainer* pCtrlCont)  
    {  
        SiteCtrl*pSite  = NULL;  
        pSite = new SiteCtrl(pCtrlCont);  
        return pSite;  
    }  
};

最后一步,或者说是倒数第二步,进行控制权的注册,
如上一篇博客那样,添加的webbrowser类中自动生成的类,中添加构造函数:

CExplorer2()  
{  
    pSiteMag=new CSiteManager();  
::AfxEnableControlContainer(pSiteMag);  
}

万里长征只剩下最后一步了,就是html的书写,如下 :

<HTML>  
<HEAD>  
<META NAME="GENERATOR" Content="Microsoft Visual Studio 8.0">  
<TITLE></TITLE>  
</HEAD>  
<script type="text/javascript">  
    function Test() {  
        window.external.TEST();  
    }  
</script>  
<BODY>  
<input type="button" value="测试" onclick="Test();" />  
</BODY>  
</HTML>

PS:到这里,网页调用C++函数就已经实现了,webbrowser是基于IE内核的,如果,我们使用webbrowser控件浏览网页,同时使用window.eternal,如果没有建立连接的话,则会出现 对象不支持此属性或方法,还有就是,该过程是无参数传递的,具有参数的传递过程,待续...

现在说下其中使用到的几个红,即 ,比如该类是A的话,那么,想要在类外进行函数定义的话,则要使用

A::XlocalClass::Method()

需要在该localClass之前加上X,进行定义

BEGIN_INTERFACE_PART(localClass,Iinterface)

END_INTERFACE_PART(localClass)

其中localClass可以认为是内嵌类,而Iinterface则是要实现的接口,在BEGIN_INTERFACE_PART和END_INTERFACE_PART之间则是该接口要实现的所有成员函数

DECLARE_INTERFACE_MAP()则是宏声明,其主要用于基类当中,而要使用

BEGIN_INTERFACE_MAP(theClass,theBase)

INTERFACE_PART(theClass,IID,localClass)

END_INTERFACE_MAP()

我们可以这样认为theClass是外部类,localClass是局部类,IID则是要实现的接口!

你可能感兴趣的:(C++,mfc,WebBrowser)