我用ATL写了个ActiveX for IE,想在运行时得到Internet Explorer_Server对象,然后再在Internet Explorer_Server中动态创建其它控件,请问怎么才能在ATL Control中获取Internet Explorer_Server对象呢?

解决方案 »

  1.   

    可以从窗口句柄得到, 用CWnd::GetControlUnknown得到IUnknown对象.
      

  2.   

    void CCPClient::DoAdvise(bool bAdvise)
    {
    HRESULT hr = S_FALSE;
    if(m_spSHWinds == 0) {
    // Create Instance ShellWindows
    if(m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK) 
    return;
    }
    IDispatchPtr spDisp;
    long nCount = m_spSHWinds->GetCount();
    // Enum all Shell Windows and list them
    for (long i = 0; i < nCount; i++) {
    _variant_t va(i, VT_I4);
    spDisp = m_spSHWinds->Item(va);
    SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);
    if (spBrowser != NULL) {
    // Get document's IDispatch
    LPDISPATCH lpDisp = NULL;
    spBrowser->get_Document(&lpDisp);
    if (lpDisp) {
    IOleContainer* pOleContainer;
    // get container
    HRESULT hr = lpDisp->QueryInterface(IID_IOleContainer, (void**)&pOleContainer);
    lpDisp->Release();
    if (FAILED(hr))
    continue;
    // hr= m_spClientSite->GetContainer (&pOleContainer); // get the page browser object
    if (SUCCEEDED(hr)) {
    IEnumUnknown* pEnumUnknown = NULL;
    hr = pOleContainer->EnumObjects (OLECONTF_EMBEDDINGS|OLECONTF_OTHERS, &pEnumUnknown);
    pOleContainer->Release();
    if (SUCCEEDED (hr)) {
    IUnknown* pUnk; 
    HRESULT hr = E_FAIL;
    // retrieve all ActiveX objects on the page
       while (pEnumUnknown->Next (1, &pUnk, NULL) == S_OK) { 
    IOleObject* pOleObject = NULL; 
    hr = pUnk->QueryInterface (IID_IOleObject, (void**)&pOleObject);  if (SUCCEEDED (hr)) { 
    IOleClientSite* pClientSite = NULL;
    pOleObject->GetClientSite (&pClientSite);
    if (pClientSite) { // suppose there's more than one CPClient object 
    IDispatch* pAmbientDispatch = NULL; 
    pClientSite->QueryInterface (IID_IDispatch, (void**)&pAmbientDispatch); 
    // get name of the found ActiveX object 
    _bstr_t bstr;
    if (pAmbientDispatch) {
    bstr = GetExtendedName(pAmbientDispatch); 
    pAmbientDispatch->Release();
    }
    _bstr_t bstName ("CPServer");
    if (bstName == bstr) {
    // get the IConnectionPointContainer interface pointer
    IConnectionPointContainer* pConnPtContainer  = NULL;
    hr = pUnk->QueryInterface (IID_IConnectionPointContainer, (void**)&pConnPtContainer);
    _ASSERT (SUCCEEDED (hr) && pConnPtContainer != NULL);
    // get the IConnectionPoint interface pointer
    IConnectionPoint* pConnPt  = NULL;
    hr = pConnPtContainer->FindConnectionPoint (DIID__ICPServerEvents, &pConnPt);
    _ASSERT (SUCCEEDED (hr) && pConnPt != NULL);
    // set/reset the CPClient's Unknown interface as the outgoing interface 
    DWORD dwCookie = 0;
    if (bAdvise) {
    // get a Cookie
    hr = pConnPt->Advise (this->GetUnknown(), &dwCookie);
    // save a Cookie into Cookie collection 
    m_vectorCookie.push_back(dwCookie);
    } else {
    // Unadvise all connection-point through Cookie collection
    for (vector<DWORD>::iterator iter = m_vectorCookie.begin(); 
    iter != m_vectorCookie.end(); iter++) {
    dwCookie = (DWORD)*iter;
    hr = pConnPt->Unadvise (dwCookie);
    if (hr == CONNECT_E_NOCONNECTION) continue;
    else break;
    }
    }
    pConnPt->Release();
    pConnPtContainer->Release();
    }
    }
    pOleObject->Release();
    }
    pUnk= NULL;
    }
    }
    }
    }
    }
    }
    m_spSHWinds.Release();
    m_spSHWinds = 0;
    if (!bAdvise) {
    m_vectorCookie.erase(m_vectorCookie.begin(), m_vectorCookie.end());
    }
    }
      

  3.   

    上面这段代码可以做参考。里面有去遍历获得当前打开的所有ie标签页的Internet Explorer_Server对象。
      

  4.   


    只要能得到ActiveX的IOleClientSite接口就行了,可以试试用下面的方法从unkonwn得到(没测试,不知道是否可行)。IOleObject *lpObject;
    lpUnk->QueryInterface(IID_IOleObject, (LPVOID*)&lpObject);
    IOleClientSite* pClientSite = NULL;
    pOleObject->GetClientSite (&pClientSite);
    得到这个接口后就简单了:IWebBrowser2 *browser = NULL;
    IServiceProvider *isp = NULL, *isp2 = NULL;pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&isp));
    isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));
    isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&browser));pClientSite->Release();
    isp->Release();
    isp2->Release();
      

  5.   

    问题解决了,可能不算完美,但至少是个途径。
    假如说只获取Internet Explorer_Server的话,直接在ATL控件里面使用::GetParent(m_hWnd)即可得到,为了保险起见,可以做个循环来取parent,直到匹配到classname为Internet Explorer_Server的HWND即可。