views:

153

answers:

1

Hello! There is the function GetLinksFromPage. She have created a links array, then I wanna pass that array to COM-object (only URLs), thus I have to convert CAtlArray< CComPtr< IDispatch> > to CComSafeArray< BSTR>. How I can do it ?

HRESULT myclass::GetLinksFromPage( const CComPtr<IHTMLDocument2>& pDoc, CAtlArray<CComPtr<IDispatch> > &arrLinks)
{
    HRESULT hr = E_FAIL;
    {
        CComPtr<IHTMLElementCollection> coll;
        hr = pDoc->get_links(&coll);
        if (SUCCEEDED(hr)&&coll)
        {
            long length;
            hr = coll->get_length(&length);
            if (SUCCEEDED(hr))
            {
                if (length)
                {
                    CComVariant ivar;
                    for (ivar.vt = VT_I4, ivar.intVal = 0; ivar.intVal<length; ivar.intVal++)
                    {
                        CComPtr<IDispatch> p_disp_ins;
                        hr = coll->item(ivar,ivar,&p_disp_ins);
                        if (SUCCEEDED(hr))
                        {
                            CComQIPtr<IHTMLElement> pCurLink(p_disp_ins);
                            if (pCurLink)
                            {
                                CComBSTR bsHRef;
                                bsHRef = GetTagAttribute(_T("href"), pCurLink, CComBSTR(_T("about:blank")));
                                if (bsHRef != _T("about:blank"))
                                {
                                    if ( isValidLink( bsHRef ) )
                                    {
                                        arrLinks.Add(p_disp_ins);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return hr;
}
A: 

Here is a reformat of what you've posted. I needed to do this to make it more understandable and more easily followed. Do note, that if one of your statements within the for loop fails you might never know. The HRESULT will be overwritten.

HRESULT myclass::GetLinksFromPage( const CComPtr<IHTMLDocument2>& pDoc, CAtlArray<CComPtr<IDispatch> > &arrLinks)
{
    CComPtr<IHTMLElementCollection> coll;
    if( FAILED( pDoc->get_links(&coll) ) )
    {
        return E_FAIL;
    }
    if( coll == NULL )
    {
        return E_FAIL;
    }

    long length;
    if (FAILED( coll->get_length(&length) ) )
    {
        return E_FAIL;
    }

    if (length == 0)
    {
        return E_FAIL;
    }

    HRESULT output = S_OK;
    CComVariant ivar;
    for (ivar.vt = VT_I4, ivar.intVal = 0; ivar.intVal<length; ivar.intVal++)
    {
        CComPtr<IDispatch> p_disp_ins;
        if (FAILED( coll->item(ivar,ivar,&p_disp_ins) ) )
        {
            output = E_FAIL;
            continue;
        }

        CComQIPtr<IHTMLElement> pCurLink(p_disp_ins);
        if (pCurLink == NULL )
        {
            output = E_FAIL;
            continue;
        }

        CComBSTR bsHRef = GetTagAttribute(_T("href"), pCurLink, CComBSTR(_T("about:blank")));
        if (bsHRef != _T("about:blank") && isValidLink( bsHRef ) )
        {
            arrLinks.Add(p_disp_ins);
        }
    }

    return output;
}

You may want to return something else in my "modification." Now, onto your question: I don't see how you're going to do it since IDispatch is just an augmented IUnknown. I'm not familiar with all of ATL so I don't know what could be being sent there. I'd need more context and I can't get it from the type. Sorry I can't be of more help.

wheaties
yes. But this function is just example.The problem is: convert CAtlArray< CComPtr< IDispatch> > to CComSafeArray< BSTR>.
cpp_fanatic
IDispatch is just an augmented IUnknown with 3 extra methods. Unless you know what type it actually represents I can't help you.
wheaties