zoukankan      html  css  js  c++  java
  • C++(MFC)中WebBrowser去除3D边框的方法(实现IDocHostUIHandler接口)控制 WebBrowser 控件的外观和行为

    在 CSDN 上经常看到以下两个问题:
    1、在 MFC 应用程序中,如果创建了一个 WebBrowser 控件(包括 CHtmlView 在内),如何可以把该控件的三维边框禁止掉?
    2、在 MFC 应用程序中,如果创建了一个 WebBrowser 控件(包括 CHtmlView 在内),如何可以把该控件的滚动条禁止掉?

    其实,这两个问题的解决办法是一样的。待老汉从头道来。

    从 Internet Explorer 4.0 开始,WebBrowser 控件的容器可以通过 IDocHostUIHandler 接口对 WebBrowser 控件的外观和某些行为进行定制。上述的两个问题,均可以通过实现该接口来达到我们的目的。但是,由于程序员自己实现 WebBrowser 控件的容器是一件很痛苦的事情,而且 MFC 中的 CHtmlView 和在 IDE 中插入 WebBrowser 控件后生成的包装类已经具有比较完整的功能封装,故罕有人愿意从头再开发自己的容器。不过令人遗憾的是,随 Visual C++ 6.0 发布的 MFC 4.2 版本中并没有对 IDocHostUIHandler 接口进行支持(顺便说一句,从 Visual C++ 7.0 开始,MFC 已经对该接口进行了支持),所以这些问题在 Visual C++ 6.0 中比较突出。

    为了解决此问题,老汉特意写了一个类来完成此工作(代码见下)。该类名为 CWebUIController,使用很简单,以对话框上包含了 WebBrowser 控件为例:

    假设对话框上的 WebBrowser 控件对应的变量名为 m_webNavigator,则需要以下步骤:

    1、向对话框类中添加 CWebUIController m_webUICtrl;

    2、在对话框的 OnInitDialog 函数中加入以下代码:

     LPUNKNOWN pUnk = m_webNavigator.GetControlUnknown();
    if(pUnk != NULL)
    {
    IWebBrowser2* pWB2 = NULL;
    HRESULT hr = pUnk->QueryInterface(IID_IWebBrowser2, (void**)&pWB2);
    if(SUCCEEDED(hr) && pWB2 != NULL)
    {
    m_webUICtrl.Enable3DBorder(FALSE); // 此代码禁止三维边框
    // m_webUICtrl.EnableScrollBar(FALSE); // 此代码禁止滚动条
    m_webUICtrl.SetWebBrowser(pWB2);
    pWB2->Release();
    }
    } 

    3、在对话框的 OnDestroy 函数中加入以下代码:

    m_webUICtrl.SetWebBrowser(NULL); 

    也可以在运行时调用 Enable3DBorder() 或者 EnableScrollBar(),调用完成后请调用 WebBrowser 控件的刷新功能。

    该类实现于一个独立的头文件 WebUIController.h 中,其完整源代码如下;从源代码中不难看出,还可以很容易的扩充此类的功能,例如控制关联菜单的显示等等。

    WebUIController.h 源代码:

    #pragma once
    // class name: CWebUIController  
    // author:     Dandy Cheung  
    // email:      dandycheung@21cn.com  
    // date:       2005-3-18  
    
    #ifndef __WEBUICONTROLLER_H__  
    #define __WEBUICONTROLLER_H__  
    
    #if _MSC_VER > 1000  
    #pragma once  
    #endif // _MSC_VER > 1000  
    
    #include <MSHTMHST.H>  
    #include <EXDISP.H>  
    #include <EXDISPID.H>  
    
    inline
    HRESULT _CoAdvise(IUnknown* pUnkCP, IUnknown* pUnk, const IID& iid, LPDWORD pdw)
    {
        IConnectionPointContainer* pCPC = NULL;
        IConnectionPoint* pCP = NULL;
        HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
        if (SUCCEEDED(hRes) && pCPC != NULL)
        {
            hRes = pCPC->FindConnectionPoint(iid, &pCP);
            if (SUCCEEDED(hRes) && pCP != NULL)
            {
                hRes = pCP->Advise(pUnk, pdw);
                pCP->Release();
            }
    
            pCPC->Release();
        }
    
        return hRes;
    }
    
    inline
    HRESULT _CoUnadvise(IUnknown* pUnkCP, const IID& iid, DWORD dw)
    {
        IConnectionPointContainer* pCPC = NULL;
        IConnectionPoint* pCP = NULL;
        HRESULT hRes = pUnkCP->QueryInterface(IID_IConnectionPointContainer, (void**)&pCPC);
        if (SUCCEEDED(hRes) && pCPC != NULL)
        {
            hRes = pCPC->FindConnectionPoint(iid, &pCP);
            if (SUCCEEDED(hRes) && pCP != NULL)
            {
                hRes = pCP->Unadvise(dw);
                pCP->Release();
            }
    
            pCPC->Release();
        }
    
        return hRes;
    }
    
    class CWebUIController : public DWebBrowserEvents2, public IDocHostUIHandler
    {
        ULONG m_uRefCount;
    
        IWebBrowser2* m_pWebBrowser2;
        DWORD m_dwCookie;
    
        BOOL m_bEnable3DBorder;
        BOOL m_bEnableScrollBar;
    
    public:
        CWebUIController() : m_uRefCount(0), m_pWebBrowser2(NULL), m_dwCookie(0)
        {
            m_bEnable3DBorder = TRUE;
            m_bEnableScrollBar = TRUE;
        }
    
        virtual ~CWebUIController()
        {
        }
    
    protected:
        // IUnknown Methods  
        STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
        {
            *ppvObject = NULL;
    
            if (IsEqualGUID(riid, DIID_DWebBrowserEvents2) ||
                IsEqualGUID(riid, IID_IDispatch))
            {
                *ppvObject = (DWebBrowserEvents2*)this;
                AddRef();
                return S_OK;
            }
            else if (IsEqualGUID(riid, IID_IDocHostUIHandler) ||
                IsEqualGUID(riid, IID_IUnknown))
            {
                *ppvObject = (IDocHostUIHandler*)this;
                AddRef();
                return S_OK;
            }
    
            return E_NOINTERFACE;
        }
    
        STDMETHOD_(ULONG, AddRef)(void)
        {
            m_uRefCount++;
            return m_uRefCount;
        }
    
        STDMETHOD_(ULONG, Release)(void)
        {
            m_uRefCount--;
            ULONG uRefCount = m_uRefCount;
            if (uRefCount == 0)
                delete this;
    
            return uRefCount;
        }
    
        // IDispatch Methods  
        STDMETHOD(GetTypeInfoCount)(unsigned int FAR* pctinfo)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
        {
            return E_NOTIMPL;
        }
    
    
        STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames,
            unsigned int cNames, LCID lcid, DISPID FAR* rgDispId)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
            DISPPARAMS* pDispParams, VARIANT* pvarResult,
            EXCEPINFO* pexcepinfo, UINT* puArgErr)
        {
            if (!pDispParams)
                return E_INVALIDARG;
    
            switch (dispidMember)
            {
                //  
                // The parameters for this DISPID are as follows:  
                // [0]: URL to navigate to - VT_BYREF|VT_VARIANT  
                // [1]: An object that evaluates to the top-level or frame  
                //      WebBrowser object corresponding to the event.   
            case DISPID_NAVIGATECOMPLETE2:
    
                //  
                // The IDocHostUIHandler association must be set  
                // up every time we navigate to a new page.  
                //  
                if (pDispParams->cArgs >= 2 && pDispParams->rgvarg[1].vt == VT_DISPATCH)
                    SetCustomDoc(pDispParams->rgvarg[1].pdispVal);
                else
                    return E_INVALIDARG;
    
                break;
    
            default:
                break;
            }
    
            return S_OK;
        }
    
        // IDocHostUIHandler Methods  
    protected:
        STDMETHOD(ShowContextMenu)(DWORD dwID, POINT FAR* ppt, IUnknown FAR* pcmdtReserved,
            IDispatch FAR* pdispReserved)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(GetHostInfo)(DOCHOSTUIINFO FAR* pInfo)
        {
            if (pInfo != NULL)
            {
                pInfo->dwFlags |= (m_bEnable3DBorder ? 0 : DOCHOSTUIFLAG_NO3DBORDER);
                pInfo->dwFlags |= (m_bEnableScrollBar ? 0 : DOCHOSTUIFLAG_SCROLL_NO);
            }
    
            return S_OK;
        }
    
        STDMETHOD(ShowUI)(DWORD dwID, IOleInPlaceActiveObject FAR* pActiveObject,
            IOleCommandTarget FAR* pCommandTarget,
            IOleInPlaceFrame  FAR* pFrame,
            IOleInPlaceUIWindow FAR* pDoc)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(HideUI)(void)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(UpdateUI)(void)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(EnableModeless)(BOOL fEnable)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(OnFrameWindowActivate)(BOOL fActivate)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow FAR* pUIWindow,
            BOOL fRameWindow)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(TranslateAccelerator)(LPMSG lpMsg, const GUID FAR* pguidCmdGroup,
            DWORD nCmdID)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(GetOptionKeyPath)(LPOLESTR FAR* pchKey, DWORD dw)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(GetDropTarget)(IDropTarget* pDropTarget,
            IDropTarget** ppDropTarget)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(GetExternal)(IDispatch** ppDispatch)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(TranslateUrl)(DWORD dwTranslate, OLECHAR* pchURLIn,
            OLECHAR** ppchURLOut)
        {
            return E_NOTIMPL;
        }
    
        STDMETHOD(FilterDataObject)(IDataObject* pDO, IDataObject** ppDORet)
        {
            return E_NOTIMPL;
        }
    
    public:
        HRESULT SetWebBrowser(IWebBrowser2* pWebBrowser2)
        {
            // Unadvise the event sink, if there was a  
            // previous reference to the WebBrowser control.  
            if (m_pWebBrowser2)
            {
                _CoUnadvise(m_pWebBrowser2, DIID_DWebBrowserEvents2, m_dwCookie);
                m_dwCookie = 0;
                // _CoUnadvise中就已经被Release         //  m_pWebBrowser2->Release();  
            }
    
            m_pWebBrowser2 = pWebBrowser2;
            if (pWebBrowser2 == NULL)
                return S_OK;
    
            m_pWebBrowser2->AddRef();
    
            return _CoAdvise(m_pWebBrowser2, (IDispatch*)this, DIID_DWebBrowserEvents2, &m_dwCookie);
        }
    
        void Enable3DBorder(BOOL bEnable = TRUE)
        {
            m_bEnable3DBorder = bEnable;
        }
    
        void EnableScrollBar(BOOL bEnable = TRUE)
        {
            m_bEnableScrollBar = bEnable;
        }
    
    private:
        void SetCustomDoc(LPDISPATCH lpDisp)
        {
            if (lpDisp == NULL)
                return;
    
            IWebBrowser2* pWebBrowser2 = NULL;
            HRESULT hr = lpDisp->QueryInterface(IID_IWebBrowser2, (void**)&pWebBrowser2);
    
            if (SUCCEEDED(hr) && pWebBrowser2)
            {
                IDispatch* pDoc = NULL;
                hr = pWebBrowser2->get_Document(&pDoc);
    
                if (SUCCEEDED(hr) && pDoc)
                {
                    ICustomDoc* pCustDoc = NULL;
                    hr = pDoc->QueryInterface(IID_ICustomDoc, (void**)&pCustDoc);
                    if (SUCCEEDED(hr) && pCustDoc != NULL)
                    {
                        pCustDoc->SetUIHandler(this);
                        pCustDoc->Release();
                    }
    
                    pDoc->Release();
                }
    
                pWebBrowser2->Release();
            }
        }
    };
    
    #endif // __WEBUICONTROLLER_H__  
  • 相关阅读:
    USACO 4.1 Fence Rails
    POJ 1742
    LA 2031
    uva 10564
    poj 3686
    LA 3350
    asp.net MVC 3多语言方案--再次写, 配源码
    使用Log4net记录日志
    在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求
    为什么要使用反射机制
  • 原文地址:https://www.cnblogs.com/chenjian/p/5312007.html
Copyright © 2011-2022 走看看