Search code examples
c++atlmshtml

Looking for an MSHTML wrapper for C++


I'm working with MSHTML API lately, and I find it very inconvenient. I'm more used to WinAPI then COM programming, so maybe it's just me, but consider the following example of querying the rectangle of an element;

Expectations:

RECT rc;
hr = element2->GetElementRect(&rc);

Reality:

CComPtr<IHTMLRect> rect;
hr = element2->getBoundingClientRect(&rect);
if(FAILED(hr))
    return hr;
if(!rect)
    return E_FAIL;

long left, right, top, bottom;
hr = rect->get_left(&left);
if(FAILED(hr))
    return hr;
hr = rect->get_right(&right);
if(FAILED(hr))
    return hr;
hr = rect->get_top(&top);
if(FAILED(hr))
    return hr;
hr = rect->get_bottom(&bottom);
if(FAILED(hr))
    return hr;

Am I missing something?

My question: are there any wrappers for this API? Surely, smart pointers such as CComPtr make things much easier, but still, I feel like struggling with the API.


Solution

  • One way is to use the #import directive and use the native C++ compiler COM support classes instead of ATL (such as _com_ptr_t<>).

    Your code then boils down to 2 lines of code:

    MSHTML::IHTMLElement2Ptr element;
    
    MSHTML::IHTMLRectPtr rect = element->getBoundingClientRect();
    RECT rc = { rect->left, rect->top, rect->right, rect->bottom };
    

    Import the mshtml stuff like this:

    #pragma warning(push)
    // warning C4192: automatically excluding '<xyz>' while importing type library 'mshtml.tlb'
    #pragma warning(disable: 4192)
    #import <mshtml.tlb>
    #pragma warning(pop)
    

    All the boiler-plate code is hidden because #import automatically creates property wrappers and methods doing HRESULT checking.