我再我做的toolvar,setsite()中想得到IWebBrowser2,为什么不行?
CComPtr<IWebBrowser2>  m_spWebBrowser;
HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);

解决方案 »

  1.   

    如果正常实现 IObjectWithSite::SetSite 就是这样拿到IWebBrowser2你看看是不是你实现IObjectWithSite有问题
      

  2.   

    返回值hr=0x80004002;
    E_NOINTERFACE   0x80004002  不支持接口
    难道说toolbar不能得到iWebBrowser2接口?
      

  3.   

    当然可以,肯定是你的代码什么地方有问题把和IObjectWithSite相关的部分贴出来看看
      

  4.   

    ////////.h
    CComPtr<IWebBrowser2>  m_spWebBrowser;///////.cpp
    STDMETHODIMP CToolBar::SetSite(IUnknown *pUnkSite)
    {
    if( NULL == pUnkSite ) // NULL 表示正在关闭
    {
    m_spSite.Release(); // 则释放先前保存的接口指针
    }
    else // 非NULL 表示正在建立
    {
    //获得dll路径
    GetModuleFileName(_Module.m_hInst, _szFilePath, MAX_PATH); 
    char* temp=strrev(_szFilePath);
    char* i=strchr(temp,'\\');
    strcpy(_szFilePath,i);
    temp=strrev(_szFilePath);
    strcpy(_szFilePath,temp);                //得到IWebBrowser2
    HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);//单步调试到这里hr返回不支持接口 // 首先通过 QueryInterface 取得 IOleWindow 接口指针
    CComQIPtr< IOleWindow, &IID_IOleWindow > spOleWindow(pUnkSite);
    // 然后调用 IOleWindow::GetWindow 取得浏览器栏的窗口句柄
    if( spOleWindow )
    spOleWindow->GetWindow(&m_hwndParent);
    if( !m_hwndParent )
                            return E_FAIL;
            if(!RegisterAndCreateWindow())
                            return E_FAIL;
    if( !m_hWnd )
                            return E_FAIL;
    m_spSite = pUnkSite;
    if( !m_spSite )
                  return E_FAIL;
    }
    return S_OK;
    }
    帮忙看一下谢谢了先
      

  5.   

    /////////////////////////////////////////////////////////////////////////////
    // CToolBar
    class ATL_NO_VTABLE CToolBar : 
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CToolBar, &CLSID_ToolBar>,
    public IObjectWithSiteImpl<CToolBar>,
    public IDispatchImpl<IToolBar, &IID_IToolBar, &LIBID_BANDSLib>,
    public IPersistStreamInitImpl<CToolBar>, // 手工添加持续性接口
    public IDeskBand
    {
    public:
    CToolBar()
    {
    m_bRequiresSave = FALSE; // 不需要保存持续性数据
    m_hwndParent = NULL; // 工具栏的窗口句柄
    m_BarHeight=0;
    m_BarWidth=0;
    m_AdNum=0;
    m_LeftIsFlash= FALSE;
    m_RightIsFlash= FALSE;
    m_LeftPicture=NULL;
    m_RightPicture=NULL;
    }DECLARE_REGISTRY_RESOURCEID(IDR_TOOLBAR)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CToolBar)
    COM_INTERFACE_ENTRY(IToolBar)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(IObjectWithSite)
    // COM_ITERFACE_ENTRY2 表示:
    // 如果想查询前一个接口指针,则提供后一个接口指针
    // 因为,后一个派生自前一个
    COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit) //手工添加
    COM_INTERFACE_ENTRY2(IPersistStream, IPersistStreamInit) //手工添加
    COM_INTERFACE_ENTRY(IPersistStreamInit) //手工添加
    // COM_INTERFACE_ENTRY_IID 表示
    // 以指定 IID 的方式提供接口入口表
    COM_INTERFACE_ENTRY_IID(IID_IDeskBand,IDeskBand) //手工添加
    END_COM_MAP()BEGIN_PROP_MAP(CToolBar) // 使用 IPersistStreamInitImpl 所必须的
    END_PROP_MAP() // 属性表。需要手工添加/**************************************************
    以下是需要实现的 接口函数 和 成员变量 的声明
    ***************************************************/
    // IObjectWithSite
    STDMETHOD(SetSite)(/*[in]*/ IUnknown *pUnkSite);
    STDMETHOD(GetSite)(/*[in]*/ REFIID riid, /*[out]*/ LPVOID *ppvReturn);// IPersistStreamInit
    BOOL m_bRequiresSave; // 使用 IPersistStreamInitImpl 所必须的// IOleWindow
    STDMETHOD(GetWindow)(/*[out]*/ HWND * phwnd);
    STDMETHOD(ContextSensitiveHelp)(/*[in]*/ BOOL fEnterMode);// IDockingWindow
    STDMETHOD(CloseDW)(/*[in]*/ DWORD dwReserved);
    STDMETHOD(ResizeBorderDW)(/*[in]*/ LPCRECT prcBorder, /*[in]*/ IUnknown* punkToolbarSite, /*[in]*/ BOOL fReserved);
    STDMETHOD(ShowDW)(/*[in]*/ BOOL bShow);// IDeskBand
    STDMETHOD(GetBandInfo)(/*[in]*/ DWORD dwBandID, /*[in]*/ DWORD dwViewMode,  DESKBANDINFO* pdbi);
    // 由于程序中没有调用容器的 IOleCommandTarget::Exec() 函数,
    // 所以下面两个成员变量,并没有使用
    DWORD m_dwViewMode;
    DWORD m_dwBandID;// IToolBar
    private:
    HWND m_hwndParent; // 保存工具栏的窗口句柄
    HWND m_hWnd; // 保存工具栏的子窗口句柄
    BOOL m_bFocus;
    CComPtr<IWebBrowser2>  m_spWebBrowser;
    // 保存IE的 IInputObjectSite 接口m_spSite。这个不是必须的。
    // 如果定制的浏览器栏中有用户输入的窗口元素,那么你需要实现
    // IInputObject 接口,这样 IE 才能够控制输入焦点。
    CComQIPtr< IInputObjectSite, &IID_IInputObjectSite > m_spSite;
    }
    .h中的ctoolbar的定义
      

  6.   


    问题不在这里,应该是你的BHO被explorer加载了,不是被IE加载的dllmain初始化的时候,判断加载的进程是否是explorer.exe,是的话,就return;,dll自己卸载,这样来保证自己只被IE加载在dllmain中:
    if (dwReason == DLL_PROCESS_ATTACH)
    {
    TCHAR pszLoader[MAX_PATH];
    GetModuleFileName(NULL, pszLoader, MAX_PATH);
    _tcslwr(pszLoader);
    if (_tcsstr(pszLoader, _T("explorer.exe"))) 
       return FALSE;
    }
      

  7.   

    // 通过 IServiceProvider::QueryService 取得IE的主框架 IWebBrowser2 指针
    CComQIPtr < IServiceProvider, &IID_IServiceProvider> spSP(pUnkSite);
    if( !spSP ) return E_FAIL; spSP->QueryService( SID_SWebBrowserApp, &m_spFrameWB2 );//+++.h中声明的
    if( !m_spFrameWB2) return E_FAIL;