Tech Support > Microsoft Windows > Development Resources > How to get a render from IHTMLElement ?
How to get a render from IHTMLElement ?
Posted by moonfacell@gmail.com on May 8th, 2008


Hi guys,

I want to capture html using win32 api and ATL, not using MFC.
I use a IE control to load a web page, and can get IHTMLElement from
the control. But I can NOT get "IHTMLElementRender" through
"QueryInterface(...)", it returns 0x80004002(E_NOINTERFACE: No such
interface supported.)

My code is as below, it can successfully load the web page, but can't
save it as image.

-----------------------------

#include "stdafx.h"
#include "mshtml.h"
#include <Exdisp.h> //for IWebBrowser2

#include <atlwin.h> //for CAxWindow
#include <atltypes.h> //for CRect

#include <atlstr.h>
#include <atlimage.h>//for CImage

#include <assert.h>

void TestIEControl()
{
CoInitialize(NULL);

CComPtr<IWebBrowser2> pBrowser;

CoCreateInstance(
CLSID_InternetExplorer,
NULL,
CLSCTX_LOCAL_SERVER,
IID_IWebBrowser2,
(void**)&pBrowser
);

CString url(L"www.google.com");
BSTR ole_url = url.AllocSysString();

HRESULT hr = pBrowser->put_Visible(TRUE);
assert(SUCCEED(hr));

VARIANT varEmpty;
VariantInit(&varEmpty);

hr = pBrowser->Navigate(ole_url, &varEmpty, &varEmpty, &varEmpty,
&varEmpty);
assert(SUCCEEDED(hr));
if(!SUCCEEDED(hr))
{
pBrowser->Quit();
}

::SysFreeString(ole_url);

Sleep(2000);

CComPtr<IDispatch> pDisp;
hr = pBrowser->get_Document(&pDisp);
assert(SUCCEEDED(hr));

CComPtr<IHTMLDocument2> pDoc;
hr = pDisp->QueryInterface(IID_IHTMLDocument2, (void**)&pDoc);
assert(SUCCEEDED(hr));

CComPtr<IHTMLElement> pElement;
hr = pDoc->get_body(&pElement);
assert(SUCCEEDED(hr));

int iWidth = 800;
int iHeight = 600;

CImage img;
BOOL bCreated = img.Create(iWidth, -iHeight, 24);
assert(bCreated);
HDC dcImg = img.GetDC();
assert(dcIm);

HDC memDc = ::CreateCompatibleDC(dcImg);
assert(memDc != NULL);

HBITMAP hBitmap = ::CreateCompatibleBitmap(memDc, iWidth,
iHeight);
assert(hBitmap != NULL);

//img.Attach(hBitmap);

::SelectObject(memDc, hBitmap);

CComPtr<IHTMLElementRender> pRender;
hr = pElement->QueryInterface(IID_IHTMLElementRender,
(void**)&pRender);
//Fail here! pRender is NULL.

//TODO IHTMLElementRender Fail
//CComQIPtr<IHTMLElementRender> pRender;
//pRender = pElement;
if(!pRender)
printf("pElement->QueryInterface(IID_IHTMLElementRender...Fail
\n");
printf("%x\n", hr);
assert(pRender != NULL);

hr = pRender->DrawToDC(memDc);
assert(SUCCEEDED(hr));

BOOL rst = ::BitBlt(
dcImg, 0, 0, 800, 600,
memDc, 0, 0,
SRCCOPY);

assert(rst);

rst = ::GdiFlush();
assert(rst);

hr = img.Save(L"rst.bmp");
assert(SUCCEEDED(hr));
/*
::SelectObject(memDc, NULL);
rst = :eleteObject(hBitmap);
assert(rst);
*/
img.ReleaseDC();

((IWebBrowser2*)pBrowser)->Release();

CoUninitialize();
}

int _tmain(int argc, _TCHAR* argv[])
{
TestIEControl();
return 0;
}


Thank you for any possible suggestion and feedback,


-----------------------------

Posted by Sebastian G. on May 8th, 2008


moonfacell@gmail.com wrote:

[...]


Wait a moment... you're loading a webpage from the internet (that is, an
untrustworthy network), which is a gross security vulnerability. And since
it succeeds, you must have misconfigured IE and most likely infected the
machine.

Posted by moonfacell@gmail.com on May 9th, 2008


On 5ÔÂ8ÈÕ, ÏÂÎç9ʱ35·Ö, "Sebastian G." <se...@seppig..de> wrote:
Yes. I also tried to call Sleep(5000) to pend for 5 seconds, but still
can NOT get the render interface.
I think somethings were wrong in creating the control. But I can't
finger it out.
Anyone help me?

Thanks !!!


Similar Posts