通过IWebBrowser2的Navigate2来实现快照功能的两个问题

Nepalon 2008-09-18 02:41:08
1、通过IWebBrowser2的Navigate2来实现快照,怎样取得整个页面的快照,而不是显示的部份?我在代码中通过Navigate2来打开网页,然后render到image中来取得网页快照,但取得的是当前显示部份的而不是整个网页的。
2、在取得有些网页的快照时有部份内容会无法显示,如http://sports.sina.com.cn/中左边的flash。还有在快照www.sina.com.cn时,由于sina会在显示时显示一个大图片,所以在快照图片中那个大图片的地方也会是一片空白,且sina首页的用户登录那一个菜单条也无法显示。
3、怎样在IWebBrowser2设置是否屏蔽java、javascript、ActiveX这种功能?

这3个问题搞了两周了,请大侠们指点,多谢!
...全文
647 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
jameshooo 2008-09-19
  • 打赏
  • 举报
回复
先告诉我你是在什么环境下使用浏览器控件的。MFC的CDHtmlDialog或者CHtmlView?还是其它?
Nepalon 2008-09-19
  • 打赏
  • 举报
回复
to jameshooo:
怎样在IWebBrowser2设置是否屏蔽java、javascript、ActiveX这种功能? 能给个例子吗?
Nepalon 2008-09-19
  • 打赏
  • 举报
回复
不好意思,刚才是我的代码写错地方了,按你的方法改了之后就可以了,非常感谢!
jameshooo 2008-09-19
  • 打赏
  • 举报
回复
原因未知,我也没辙了
Nepalon 2008-09-19
  • 打赏
  • 举报
回复
我按你的方法,修改了代码:
//pRender->DrawToDC(destDC);

RECT rc = {0, 0, 1024, 2048};
OleDraw((LPUNKNOWN)m_pBrowser, DVASPECT_CONTENT, destDC, &rc);

还是不行,结果一样。

页面会有部份内容无法显示的问题有解决的办法吗?
jameshooo 2008-09-19
  • 打赏
  • 举报
回复
调用这个试试:
RECT rc = {0, 0, 1024, 2048};
OleDraw((LPUNKNOWN)m_pBrowser, DVASPECT_CONTENT, destDC, &rc);
Nepalon 2008-09-19
  • 打赏
  • 举报
回复
我在代码如下:
/*
szSrcFilename为页面URL
szDestFilename为输出的图片名称
srcSize为要快照的页面尺寸
startPoint为快照的页面起始点传票
outputSize为输出的图片大小
*/
BOOL CCreateHTMLImage::CreateImage(LPCTSTR szSrcFilename, LPCTSTR szDestFilename, CSize srcSize, CSize startPoint, CSize outputSize)
{
ASSERT(GetSafeHwnd());
ASSERT(IsWindow(GetSafeHwnd()));
ASSERT(szSrcFilename);
ASSERT(AfxIsValidString(szSrcFilename));
ASSERT(szDestFilename);
ASSERT(AfxIsValidString(szDestFilename));

CRect rect;
CWnd m_pBrowserWnd;
CComPtr<IWebBrowser2> m_pBrowser;

if (!CWnd::Create(NULL, NULL, WS_CHILD, rect, pParent, 0, NULL))
return FALSE;

if (!m_pBrowserWnd.CreateControl(CLSID_WebBrowser, _T(""), WS_VISIBLE | WS_CHILD, rect, this, CHILDBROWSER))
{
DestroyWindow();
return FALSE;
}

LPUNKNOWN lpUnk = m_pBrowserWnd.GetControlUnknown();
HRESULT hr = lpUnk->QueryInterface(IID_IWebBrowser2, (void**) &m_pBrowser);

if (!SUCCEEDED(hr))
{
m_pBrowser = NULL;
m_pBrowserWnd.DestroyWindow();
DestroyWindow();
return FALSE;
}

CRect rect(CPoint(0, 0), srcSize);

// The WebBrowswer window size must be set to our srcSize
// else it won't render everything
//把控件指定到要快照的网页的尺寸大小
MoveWindow(&rect);
m_pBrowserWnd.MoveWindow(&rect);

COleVariant vUrl(szSrcFilename, VT_BSTR),
vFlags(long(navNoHistory | navNoReadFromCache | navNoWriteToCache), VT_I4),
vNull(LPCTSTR(NULL), VT_BSTR);
COleSafeArray vPostData;

if (m_pBrowser->Navigate2(&vUrl, &vFlags, &vNull, &vPostData, &vNull) == S_OK)
// We have to pump messages to ensure the event handler (DocumentComplete)
// is called.
//调用这句代码的作用是产生线程阻塞,直到DocumentComplete函数被高用,防止页面还没加载完就生成图片
RunModalLoop();
else
return FALSE;


// We only get here when DocumentComplete has been called, which calls EndModalLoop
// and causes RunModalLoop to exit.
IDispatch *pDoc = (IDispatch *) NULL;
HRESULT hr = m_pBrowser->get_Document(&pDoc);
IHTMLWindow2 *pWin = (IHTMLWindow2 *)NULL;
((IHTMLDocument2 *) pDoc)->get_parentWindow(&pWin);

pWin->scroll(startPoint.cx, startPoint.cy);

if (FAILED(hr))
return FALSE;

return CreateImage((IHTMLDocument2 *) pDoc, szDestFilename, srcSize, outputSize);
}

BOOL CCreateHTMLImage::CreateImage(IHTMLDocument2 *pDoc, LPCTSTR szDestFilename, CSize srcSize, CSize outputSize)
{
USES_CONVERSION;
ASSERT(szDestFilename);
ASSERT(AfxIsValidString(szDestFilename));
ASSERT(pDoc);

// Get our interfaces before we create anything else
IHTMLElement *pElement = (IHTMLElement *) NULL;
IHTMLElementRender *pRender = (IHTMLElementRender *) NULL;

// Let's be paranoid...
if (pDoc == (IHTMLDocument2 *) NULL)
return FALSE;

pDoc->get_body(&pElement);

if (pElement == (IHTMLElement *) NULL)
return FALSE;

pElement->QueryInterface(IID_IHTMLElementRender, (void **) &pRender);

if (pRender == (IHTMLElementRender *) NULL)
return FALSE;

CFileSpec fsDest(szDestFilename);
CBitmapDC destDC(srcSize.cx, srcSize.cy);

pRender->DrawToDC(destDC);

CBitmap *pBM = destDC.Close();

Bitmap *gdiBMP = Bitmap::FromHBITMAP(HBITMAP(pBM->GetSafeHandle()), NULL);

//新建一个bmp图片
Image *bitmap = (Image *)new Bitmap(outputSize.cx, outputSize.cy);
//新建一个画板
Graphics *g = Graphics::FromImage(bitmap);
//设置高质量插值法
g->SetInterpolationMode(InterpolationModeHighQuality);
//设置高质量,低速度呈现平滑程度
g->SetSmoothingMode(SmoothingModeHighQuality);
//清空一下画布
g->Clear(Color.Blue);
//在指定位置画图
g->DrawImage(gdiBMP, 0, 0, outputSize.cx, outputSize.cy);
//保存高清晰度的缩略图
bitmap->Save(A2W(((LPCSTR)(LPCTSTR)(fsDest.GetFullSpec()))), &m_encoderClsid);

delete gdiBMP;
delete g;
delete bitmap;
delete pBM;

return TRUE;
}
下面是调用代码:
m_pHTMLImage->CreateImage("http://www.sina.com", "c:\\sina_0-768.jpg", CSize(1024, 2048), CSize(0, 0), CSize(1024, 2048))
我这里偷赖指定了页面大小为1024x2048,新浪的页面绝对超过这个尺寸了。
Nepalon 2008-09-19
  • 打赏
  • 举报
回复
TO jameshooo:
对于我的第一个问题,我写错了。其实不是图片显示不出来,而是页面中有部分内容显示不出来
还有ebay(www.ebay.com)也是这样,页面的头显示不出来(logo部份)。

而sports.sina.com则是有个flash无法显示

我在全屏快照时,已经按你的方法来指定render的调试了,而且我等待时间是1分钟,还是得出来的是一片空白,之前不能显示的页面部份和页面的其余部份还是不能显示。我在render时指定尺寸为1024x2048
jameshooo 2008-09-19
  • 打赏
  • 举报
回复
最后一句还是改成 return CWnd::OnAmbientProperty(pSite, dispid, pval); 吧。
里面的pvar 也改成 pval
jameshooo 2008-09-19
  • 打赏
  • 举报
回复
本质上没有区别,但是如果是MFC类的话处理起来方便一点,在CHtmlView的派生类中重载下面的CWnd虚函数:
virtual BOOL OnAmbientProperty(COleControlSite* pSite, DISPID dispid, VARIANT* pvar )
{
if (dispid == DISPID_AMBIENT_DLCONTROL)
{
V_VT(pvar) = VT_I4;
V_I4(pvar) = DLCTL_NO_SCRIPTS | DLCTL_NO_JAVA | DLCTL_NO_RUNACTIVEXCTLS;
return TRUE;
}

return FALSE;
}

Nepalon 2008-09-19
  • 打赏
  • 举报
回复
是通过CHtmlView?
顺便问一下,这些方式有什么区别?
yjgx007 2008-09-18
  • 打赏
  • 举报
回复
ouch,why dont u use printing out in IE?
jameshooo 2008-09-18
  • 打赏
  • 举报
回复
1、计算文档的高度,在render时按照此高度设置DC的矩形
2、DocumentComplete事件发生时图片可能是没有下载完成的,此时显示将是一个跟图片一样大小的空白,你可以在DocumentComplete之后设置定时器等一段时间再试
3、不知道你是通过MFC提供的类来显示的浏览器控件还是自己实现容器接口的。用SetHostFlags来设置DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE,或者在实现的IDocHostUIHandler的GetHostInfo方法里面设置。其实更深层解决办法是在实现容器接口的同时实现IDispatch接口,在Invoke方法里面判断DISPID为DISPID_AMBIENT_DLCONTROL时返回一些控制标志即可,比如:
DLCTL_NO_SCRIPTS
DLCTL_NO_JAVA
DLCTL_NO_RUNACTIVEXCTLS
Nepalon 2008-09-18
  • 打赏
  • 举报
回复
还有,只要界面中有内容无法显示,那么调用以下实现滚动的代码就会失效:
((IHTMLDocument2 *) pDoc)->get_parentWindow(&pWin);
pWin->scroll(0, yIndex);
Nepalon 2008-09-18
  • 打赏
  • 举报
回复
上面总是有的地方讲得有错误,下面更正一下:
1、对于sina首页应该是有部份内容显示不出来。

2、对于flash总是,好象也不是所有flash都显示不出来,只有有部份显示不出来而已。象新浪首页有的flash就能显示。但sports.sina.com.cn中的那个就显示不出来。

3,055

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC HTML/XML
社区管理员
  • HTML/XML社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧