Skip to content

IE获取元素样式

Published: at 04:01 PM | 2 min read

IE浏览器获取元素样式,通过正常方式获取不了。

这种方法获取不了:

				CComPtr<IHTMLStyle> pHtmlStyle;
				if (!FAILED(m_pHtmlElement->get_style(&pHtmlStyle)) && pHtmlStyle != NULL) {
					if (!FAILED(pHtmlStyle->get_cssText(&bstr))) {

正确的方法:

void bstr2str(std::string &str, BSTR bstr)
{
    if (bstr == NULL)
    {
        str.clear();
    }
    else
    {
        DWORD dwRequiredSize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)bstr,
            SysStringLen(bstr), NULL, 0,
            NULL, NULL);
        LPSTR lpszBuffer = (LPSTR)malloc(dwRequiredSize + 2);
        dwRequiredSize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)bstr,
            SysStringLen(bstr), lpszBuffer, dwRequiredSize + 1,
            NULL, NULL);
        lpszBuffer[dwRequiredSize] = '\0';
        str.assign(lpszBuffer);
        free(lpszBuffer);
        SysFreeString(bstr);
    }
}


BSTR str2bstr(const char*lpsz)
{
    if (lpsz == NULL)
        return NULL;
    else
    {
        DWORD dwRequiredSize = MultiByteToWideChar(CP_UTF8, 0, lpsz,
            -1, NULL, 0);
        DWORD dwBytes = sizeof(wchar_t) * dwRequiredSize;
        LPWSTR lpwszBuffer = (LPWSTR)malloc(dwBytes + 1);
        MultiByteToWideChar(CP_UTF8, 0, lpsz,
            -1, lpwszBuffer, dwBytes);
        lpwszBuffer[dwRequiredSize] = L'\0';
        BSTR bstr = SysAllocString(lpwszBuffer);
        free(lpwszBuffer);
        return bstr;
    }

}

HRESULT getDispatchProperty(IDispatch *object, const char *property, VARIANT &value)
{
    BSTR bstr = str2bstr(property);
    DISPID dispId;
    IDispatchEx *pDispatchEx;
    static IID IDispatchEx_CLSID = { 0xa6ef9860, 0xc720, 0x11d0, {0x93, 0x37, 0x00,0xa0,0xc9,0x0d,0xca,0xa9} };
    HRESULT hr = object->QueryInterface(IDispatchEx_CLSID, reinterpret_cast<void**>(&pDispatchEx));
    if (!FAILED(hr) && pDispatchEx != NULL)
    {
        hr = pDispatchEx->GetDispID(bstr, fdexNameEnsure, &dispId);
        if (FAILED(hr))
        {
            //MZNSendDebugMessage("Unable to get property %ls", bstr);
        }
        else
        {
            DISPPARAMS dp;
            dp.cArgs = 0;
            dp.cNamedArgs = 0;
            dp.rgvarg = NULL;
            VARIANT result;
            result.vt = VT_NULL;
            UINT error;
            EXCEPINFO ei;
            ZeroMemory(&ei, sizeof ei);
            hr = pDispatchEx->InvokeEx(dispId, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dp, &value, &ei, NULL);
            if (FAILED(hr))
            {
#if 0
                MZNSendDebugMessage("Cannot get property %s", property);
                MZNSendDebugMessage("Error en InvokeEx");
                MZNSendDebugMessage("Error en %lX en attributes %d", (long)hr, (int)error);
                MZNSendDebugMessage("Error code %d ", (int)ei.wCode);
                MZNSendDebugMessage("Source %ls", ei.bstrSource);
                MZNSendDebugMessage("Description %ls", ei.bstrDescription);
#endif
            }

        }
        pDispatchEx->Release();
    }
    else
    {
        //MZNSendDebugMessage("Cannot get IDispatchEx");
    }
    SysFreeString(bstr);
    return hr;
}

void getStyleAttribute(IDispatch *object, std::string &style)
{
    VARIANT v;
    VariantInit(&v);
    HRESULT hr = getDispatchProperty(object, "style", v);
    if (FAILED(hr))
        return;

    if (!v.vt == VT_DISPATCH)
    {
        VariantClear(&v);
        return;
    }

    VARIANT v2;
    VariantInit(&v2);
    hr = getDispatchProperty(v.pdispVal, "cssText", v2);
    if (!FAILED(hr))
    {
        VARIANT result2;
        VariantInit(&result2);
        if (S_OK == VariantChangeType(&result2, &v2, 0, VT_BSTR))
        {
            bstr2str(style, result2.bstrVal);
            VariantClear(&result2);
        }
        else {
        }
        VariantClear(&v2);
    }


    v.pdispVal->Release();
    VariantClear(&v);
}