c++internet-explorereventsbhoiwebbrowser2

enumerate forms in BeforeNavigate2 event


I'm writing an IE BHO, I'd like to know how to enumerate forms in event callback. here's the code that enumerates forms in BeforeNavigate2 event, but the length is always 0.

STDMETHODIMP CEventSink::Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
{
    HRESULT hr;
    char bf[1024];

    if(!IsEqualIID(riid, IID_NULL)) 
        return DISP_E_UNKNOWNINTERFACE;

    if(dispIdMember == DISPID_BEFORENAVIGATE2) {

        IWebBrowser2* pSite = (IWebBrowser2*)pDispParams->rgvarg[6].pdispVal;

        IDispatch* pHtmlDocDispatch;
        hr = pSite->get_Document(&pHtmlDocDispatch);
        if (FAILED(hr) || !pHtmlDocDispatch) 
            return S_OK;

        IHTMLDocument2* pHtmlDoc = 0;

        hr = pHtmlDocDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&pHtmlDoc);

        if(SUCCEEDED(hr) && pHtmlDoc) {
            CComPtr<IHTMLElementCollection> pColl=NULL;
            hr = pHtmlDoc->get_forms(&pColl);

            if (SUCCEEDED (hr) && (pColl != NULL))
            {
                long nLength = 0;
                hr = pColl->get_length (&nLength);

                if(SUCCEEDED(hr)) {
                    sprintf(bf, "len = %d", nLength);
                    OutputDebugString(bf); // always 0
                }
            }
        }
    }
    return S_OK;
}

Why it always output 0?

Thanks.


Solution

  • I just copy/pasted your code in my BHO and got a non-zero length collection.

    Try that URL: http://linuxfr.org/ Use random user/password values and try to connect. That will trigger a DISPID_BEFORENAVIGATE2 and you will get 3 forms.

    So, it seems there is no form in the page your are navigating away.

    Also, your code leaks memory and is not quite correct in using COM interfaces (ag: you should QueryInterface for obtaining an IWebBrowser2 from a IDispatch.

    Rewritten:

    CComPtr<IDispatch> spIDispatch( pDispParams->rgvarg[6].pdispVal );
    CComPtr<IWebBrowser2> spIWebBrowser2;
    HRESULT hr = spIDispatch.QueryInterface<IWebBrowser2>( &spIWebBrowser2 );
    if ( SUCCEEDED( hr ) && spIWebBrowser2 ) {
        CComPtr<IDispatch> spIDispatchDoc;
        hr = spIWebBrowser2->get_Document( &spIDispatchDoc );
        if ( SUCCEEDED( hr ) && spIDispatchDoc ) {
            CComPtr<IHTMLDocument2> spIHTMLDocument2;
            hr = spIDispatchDoc.QueryInterface<IHTMLDocument2>( &spIHTMLDocument2 );
            if ( SUCCEEDED( hr ) && spIHTMLDocument2 ) {
                CComPtr<IHTMLElementCollection> spIHTMLElementCollection;
                hr = spIHTMLDocument2->get_forms( &spIHTMLElementCollection );
                if ( SUCCEEDED( hr ) && spIHTMLElementCollection ) {
                     [...]
                }
            }
        }
    }