Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Since your question is somewhat broad the solution I'm providing it somewhat large but complete and tested. If you already have a pointer to a valid IHTMLDocument or IHTMLElement object you can retrieve the location and dimensions of an element quite easily. The only requirement to get the dimensions is that the document must be attached to an IHTMLWindow / IWebBrowser object. I have included a stand along function that creates the IWebBrowser and IHTMLDocument objects for testing.</p> <p>I've included some comments to help you along the way. This was tested with Visual Studio 2010 on Windows 7 system with Internet Explorer 9. This is the result set I get from the example:</p> <blockquote> <p>Rect = x=8 y=89 width=992 height=31</p> <p>contents=hello</p> </blockquote> <pre><code>#include &lt;comutil.h&gt; // _bstr_t #include &lt;mshtml.h&gt; // IHTMLDocument and IHTMLElement #include &lt;exdisp.h&gt; // IWebBrowser2 #include &lt;atlbase.h&gt; // CComPtr #include &lt;string&gt; #include &lt;iostream&gt; // Make sure we link in the support library! #pragma comment(lib, "comsuppw.lib") static const std::wstring exampleHtml(L"&lt;body&gt;&lt;html&gt;&lt;br&gt;&lt;br&gt;&lt;p id=\"someid\"&gt;hello&lt;/p&gt;&lt;/body&gt;"); HRESULT CreateBrowserDocument( const std::wstring&amp; html, CComPtr&lt;IWebBrowser2&gt;&amp; returnBrowser, CComPtr&lt;IHTMLDocument3&gt;&amp; returnDoc); int main() { /////////////////////////////////////////////////////////////////////////// // In order to get the position and dimension of an element we need to // have a browser object that owns the document we will work on. If you // create and use a IHTMLDocument object through CoCreateInstance it does // not have any rendering capabilities by default. /////////////////////////////////////////////////////////////////////////// HRESULT hr; hr = CoInitialize(NULL); if(SUCCEEDED(hr)) { // Make sure these two items are scoped so CoUninitialize doesn't gump // us up. CComPtr&lt;IWebBrowser2&gt; browser; CComPtr&lt;IHTMLDocument3&gt; document; hr = CreateBrowserDocument(exampleHtml, browser, document); if(SUCCEEDED(hr)) { CComPtr&lt;IHTMLElement&gt; element; /////////////////////////////////////////////////////////////////// // We grab the element by id to make the example easier. in some // cases you may need to iterate through all of the elements of the // document or parent element to find the one you want the // dimensions for. /////////////////////////////////////////////////////////////////// hr = document-&gt;getElementById(_bstr_t(L"someid"), &amp;element); if(SUCCEEDED(hr) &amp;&amp; element != NULL) { /////////////////////////////////////////////////////////////// // Now that we have the browser object, document object and the // element we want to get the dimensions for .... do it the // easy way. /////////////////////////////////////////////////////////////// _bstr_t contents; long left, top, width, height; // I skip the error checking here. Add it when you implement // your solution. hr = element-&gt;get_innerHTML(contents.GetAddress()); hr = element-&gt;get_offsetLeft(&amp;left); hr = element-&gt;get_offsetTop(&amp;top); hr = element-&gt;get_offsetWidth(&amp;width); hr = element-&gt;get_offsetHeight(&amp;height); std::cout &lt;&lt; "Rect = " &lt;&lt; "x=" &lt;&lt; left &lt;&lt; " " &lt;&lt; "y=" &lt;&lt; top &lt;&lt; " " &lt;&lt; "width=" &lt;&lt; width &lt;&lt; " " &lt;&lt; "height=" &lt;&lt; height &lt;&lt; std::endl &lt;&lt; "contents=" &lt;&lt; contents &lt;&lt; std::endl; } } } CoUninitialize(); return 0; } // Here we create web browser and document objects. The additional browser // object is required for layout management. I have taken a shortcut here and // create an instance Internet Explorer instead. This allows the browser to // create and initializes a HTMLDocument when we call IWebBrowser::Navigate. HRESULT CreateBrowserDocument( const std::wstring&amp; html, CComPtr&lt;IWebBrowser2&gt;&amp; returnBrowser, CComPtr&lt;IHTMLDocument3&gt;&amp; returnDoc) { CComPtr&lt;IHTMLDocument2&gt; document; CComPtr&lt;IWebBrowser2&gt; browser; HRESULT hr; hr = CoCreateInstance( CLSID_InternetExplorer, NULL, CLSCTX_SERVER, IID_IWebBrowser2, reinterpret_cast&lt;void**&gt;(&amp;browser)); if(SUCCEEDED(hr)) { // The browser does not contain a document by default. We can force // one though by navigating to the `about` page. This is fast and // does not require an internet connection. VARIANT empty; VariantInit(&amp;empty); hr = browser-&gt;Navigate( _bstr_t(L"about:"), &amp;empty, &amp;empty, &amp;empty, &amp;empty); // Wait for the load. if(SUCCEEDED(hr)) { READYSTATE state; while(SUCCEEDED(hr = browser-&gt;get_ReadyState(&amp;state))) { if(state == READYSTATE_COMPLETE) break; } } // The browser now has a document object. Grab it. if(SUCCEEDED(hr)) { CComPtr&lt;IDispatch&gt; dispatch; hr = browser-&gt;get_Document(&amp;dispatch); if(SUCCEEDED(hr) &amp;&amp; dispatch != NULL) { hr = dispatch.QueryInterface&lt;IHTMLDocument2&gt;(&amp;document); } else { hr = E_FAIL; } } } if(SUCCEEDED(hr)) { // Since the about page is empty we can just write out our test HTML // directly to the document. Takes some effort since we need to // use a safe array to send it to the document. SAFEARRAY *pString = SafeArrayCreateVector(VT_VARIANT, 0, 1); if (pString != NULL) { VARIANT *param; hr = SafeArrayAccessData(pString, reinterpret_cast&lt;void**&gt;(&amp;param)); if(SUCCEEDED(hr)) { const _bstr_t htmlString(SysAllocString(html.c_str())); param-&gt;vt = VT_BSTR; param-&gt;bstrVal = htmlString; hr = SafeArrayUnaccessData(pString); if(SUCCEEDED(hr)) { hr = document-&gt;write(pString); document-&gt;close(); } } SafeArrayDestroy(pString); } // Set the return values if(SUCCEEDED(hr) &amp;&amp; document != NULL &amp;&amp; browser != NULL) { CComPtr&lt;IHTMLDocument3&gt; temp; hr = document.QueryInterface&lt;IHTMLDocument3&gt;(&amp;temp); if(SUCCEEDED(hr) &amp;&amp; temp != NULL) { document = temp; } else { hr = E_FAIL; } CComPtr&lt;IHTMLDocument3&gt; tempDoc; if(SUCCEEDED(hr)) { hr = document.QueryInterface&lt;IHTMLDocument3&gt;(&amp;tempDoc); } if(SUCCEEDED(hr) &amp;&amp; tempDoc != NULL) { returnDoc = tempDoc; returnBrowser = browser; } } else if(!FAILED(hr)) { hr = E_FAIL; } } return hr; } </code></pre> <p><br><br>[<strong>EDIT 1</strong>: Removed unnecessary call to <code>IWebBrowser::put_RegisterAsBrowser</code>]</p> <p>[<strong>EDIT 2</strong>: Simplified getting dimensions by using <code>IHTMLElement::get_OffsetXXX</code> instead of <code>IHTMLElement::get_clientXXX</code>]</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload