La comparaison avec des objets IDispatch pour obtenir châssis principal seulement (BHO)

StackOverflow https://stackoverflow.com/questions/2398525

  •  25-09-2019
  •  | 
  •  

Question

Je ne sais pas si quelqu'un familier avec BHO (Browser Helper Object), mais un expert en C ++ peut me aider aussi.

Dans mon BHO je veux courir la fonction que sur le châssis principal OnDocumentComplete () - le premier récipient et pas tout le Iframe dans la page en cours. (Une alternative est de mettre un peu de code que lorsque cela est le cadre principal).

Je ne peux pas trouver comment suivre quand est-il le cadre principal qui étant peuplé.

Après une recherche dans google je trouve que chaque cadre a « IDispatch * pDisp », et je dois le comparer avec un pointeur vers le premier.

Ceci est la fonction principale:

STDMETHODIMP Browsarity::SetSite(IUnknown* pUnkSite)
{
    if (pUnkSite != NULL)
    {
        // Cache the pointer to IWebBrowser2.
        HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);
        if (SUCCEEDED(hr))
        {
            // Register to sink events from DWebBrowserEvents2.
            hr = DispEventAdvise(m_spWebBrowser);
            if (SUCCEEDED(hr))
            {
                m_fAdvised = TRUE;
            }
        }
    }
    else
    {
        // Unregister event sink.
        if (m_fAdvised)
        {
            DispEventUnadvise(m_spWebBrowser);
            m_fAdvised = FALSE;
        }

        // Release cached pointers and other resources here.
        m_spWebBrowser.Release();
    }

    // Call base class implementation.
    return IObjectWithSiteImpl<Browsarity>::SetSite(pUnkSite);
}

est où je veux savoir si son la fenêtre principale (cadre) ou non:

void STDMETHODCALLTYPE Browsarity::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
  // as you can see, this function get the IDispatch *pDisp which is unique to every frame.
  //some code
}

J'ai posé cette question sur le forum Microsoft et je suis une réponse sans expliquer comment mettre en œuvre effectivement que: http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/7c433bfa-30d7-42db-980a-70e62640184c

Était-ce utile?

La solution

Qu'est-ce jeffdav suggéré est, pour tester le wether pDisp prend en charge IWebBrowser2 via QueryInterface(), et si oui, pour vérifier qu'il est le wether même objet que celui que vous avez enregistré dans SetSite().
règles de QueryInterface() ne nécessitent qu'un QI pour IUnknown résultats toujours la même valeur de pointeur, donc vous devez QI en plus de IUnknown et de comparer les pointeurs résultant.

Cela conduirait à quelque chose comme ça dans OnDocumentComplete():

IWebBrowser2* pBrowser = 0;
IUnknown *pUnk1=0, *pUnk2=0;
if(   SUCCEEDED(pDisp      ->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser))
   && SUCCEEDED(pDisp      ->QueryInterface(IID_IUnknown,     (void**)&pUnk1))
   && SUCCEEDED(m_spBrowser->QueryInterface(IID_IUnknown,     (void**)&pUnk2))
   && (pUnk1 == pUnk2)) 
{
    // ... top-level
}

... ou si vous utilisez ATL (comme m_spWebBrowser suggère):

CComQIPtr<IWebBrowser2> spBrowser(pDisp);
if(spBrowser && spBrowser.IsEqualObject(m_spWebBrowser)) {
    // ...
}

Autres conseils

Notez que je n'ai pas testé, je suis réécrire ce que dit le gars sur msdn.

:: SetSite vous obtenez un pointeur IUnknown. Appelez IUnknown :: QueryInterface sur elle (comme vous faites déjà), mais au lieu d'utiliser IID_IDispatch. Enregistrer ce pointeur quelque part, ce pointeur est le cadre de niveau supérieur.

Dans :: OnDocumentComplete vous obtenez un pointeur IDispatch, comparer celui-ci à l'ptr sauvé précédent et le tour est joué, s'il y a un match, vous êtes dans le niveau supérieur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top