Search code examples
javascriptvisual-c++comwebbrowser-control

Get IFrame's name from WebBrowser2 using VC++ COM


    VARIANT varindex,varresult;
    VariantInit(&varindex);
    VariantInit(&varresult);
    varindex.vt = VT_I4;
    varresult.vt = VT_DISPATCH;
    long lFrameNum = 0;
    CComPtr<IHTMLFramesCollection2> pFramesCollection;
    hr = m_spDoc->get_frames(&pFramesCollection); //CComPtr<IHTMLDocument2> m_spDoc
    if(FAILED(hr))
    {
        return false;
    }
    hr = pFramesCollection->get_length(&lFrameNum);
    if(FAILED(hr))
    {
        return false;
    }

    for(int i=0; i<lFrameNum; i++)
    { 
        varindex.lVal = i;
        if(pFramesCollection->item(&varindex, &varresult) == S_OK)
        {
            IDispatch *pDispatch;
            pDispatch = varresult.pdispVal;

            CComQIPtr< IHTMLFrameBase > spFrameBase(pDispatch);
            if(!spFrameBase)   return false; //failed here, E_NOINTERFACE
        }
    }

The codes here shows how to enum frames in a webpage, and get its name. I get the IDispatch of each iframe successfully, but when I tried to get IHTMLFrameBase (IID_IHTMLFrameBase), it failed with the error E_NOINTERFACE.

I am not familiar with COM, what did I do wrong? Help me please, thanks in advance.


Solution

  • Though, I didn't get the frame name directly, but I figured out how to get The IHTMLDocument2* of that specific frame. And Then, I can do something to the frame, like call its js functions etc. The codes are like below:

            VARIANT varindex,varresult;
            VariantInit(&varindex);
            VariantInit(&varresult);
            varindex.vt = VT_BSTR;
            varindex.bstrVal = "Frame Name"; //the specific frame name
            pFramesCollection->item(&varindex,&varresult);
            IHTMLWindow2* pFrameWindow;
            varresult.pdispVal->QueryInterface(IID_IHTMLWindow2, (void **)&pFrameWindow);
            IHTMLDocument2* pDoc;
            pFrameWindow->get_document(&pDoc);
            //do something ...