본문 바로가기

프로그래밍/코드 조각

Document로부터 favicon url 정보 추출하기

template<typename Char> struct CaseInsensitiveCompare {
 public:
  bool operator()(Char x, Char y) const {
    return tolower(x) == tolower(y);
  }
};

std::wstring GetFaviconUrlFromDocument(IHTMLDocument2* doc2)
{
    if (!doc2)
    {
        return std::wstring();
    }
    static std::wstring const linktag = L"LINK";

    CComPtr<IHTMLElementCollection> ielemCol;
    CComPtr<IHTMLLinkElement> lnkelem;
    if (FAILED(doc2->get_all(&ielemCol)))
    {
        return std::wstring();
    }
    CComPtr<IDispatch> displink;
    CComQIPtr<IHTMLElement, &IID_IHTMLElement> ielem;
    if (FAILED(ielemCol->tags(CComVariant(linktag), &displink)))
    {
        return std::wstring();
    }
    if (FAILED(displink->QueryInterface(IID_IHTMLElementCollection, (void**)&ielemCol)))
    {
        return std::wstring();
    }
    long count = 0;
    if (FAILED(ielemCol->get_length(&count)))
    {
        return std::wstring();
    }

    CComPtr<IDispatch> dispEnum;
    for (long i=0; i<count; i++)
    {
        CComVariant index = i;
        if (SUCCEEDED(ielemCol->item(index, index, &dispEnum)))
        {
            ielem = dispEnum;
            CComBSTR bstr;
            if (SUCCEEDED(ielem->get_tagName(&bstr)))
            {
                std::wstring tag = bstr;
                if (tag.length() == linktag.length() &&
                    std::equal(tag.begin(), tag.end(), linktag.begin(), CaseInsensitiveCompare<wchar_t>()))
                {
                    if(SUCCEEDED(ielem->QueryInterface(IID_IHTMLLinkElement, (void**)&lnkelem)) && lnkelem)
                    {
                        if(SUCCEEDED(lnkelem->get_rel(&bstr)))
                        {
                            std::wstring rel = bstr;
                            std::wstring shortcut_icon(L"shortcut icon");
                            if (rel.length() == shortcut_icon.length() &&
                                std::equal(rel.begin(), rel.end(), shortcut_icon.begin(), CaseInsensitiveCompare<wchar_t>()))
                            {
                                if(SUCCEEDED(lnkelem->get_href(&bstr)))
                                {
                                    std::wstring url = bstr;
                                    return url;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    return std::wstring();
 }