Reputation: 6911
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.
Upvotes: 0
Views: 538
Reputation: 1369
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.
Upvotes: 3