[IE编程] IE网页截图技术总结_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > [IE编程] IE网页截图技术总结

[IE编程] IE网页截图技术总结

 2012/4/24 17:13:39  touch_123  程序员俱乐部  我要评论(0)
  • 摘要:IE网页截图是IE编程中的经典问题。IE9beta发布之后我收到很多关于这方面的问题。最近我把IE和Windows中这部分相关的代码重新架构了一下,使它们能够在IE9开启硬件加速的情况下完美兼容原来GDI函数。趁着记忆还fresh,写一个总结以供大家参考。主要有以下3个接口可以实现IE网页截图。1)HRESULTIHTMLElementRender::DrawToDC(HDChDC)MSDN参考:http://msdn.microsoft.com/en-us/library/aa752273
  • 标签:总结 网页 编程 技术

IE网页截图是IE编程中的经典问题。 IE9 beta发布之后我收到很多关于这方面的问题。 最近我把IE和Windows中这部分相关的代码重新架构了一下,使它们能够在IE9开启硬件加速的情况下完美兼容原来GDI函数。 趁着记忆还fresh, 写一个总结以供大家参考。

?

主要有以下3接口可以实现IE网页截图。

?

1) HRESULT?IHTMLElementRender::DrawToDC(HDC hDC)

?

MSDN参考:?http://msdn.microsoft.com/en-us/library/aa752273(VS.85).aspx

?

简单代码示例:

?

[c-sharp]?view plaincopy
  1. IHTMLDocument3?*pDoc?=?...;??//得到IHTMLDocument3指针??
  2. IHTMLElement?*pDocElement?=?NULL;??
  3. pDoc->get_documentElement(&pDocElement?);??
  4. IHTMLElementRender?*pRender?=??NULL;??
  5. pDocElement?->QueryInterface(IID_IHTMLElementRender,?(void?**)?&pRender);??
  6. pDocElement->DrawToDC(hImageDC);??

?

?

注意事项:?Quirks 模式下,documentElement不存在, 请使用BODY元素。

?

优点:?可以画某个特定的HTML元素

缺点:

需要判断是不是Quirks模式下,进而决定拿documentElement元素还是BODY元素的的指针;

只能按目前屏幕显示大小截取,不支持缩放;

在有些情况就是当网页由frames 组成或者是个内嵌的doc/pdf文档,该可能会失败;

?

2) HRESULT?IViewObject::Draw( DWORD dwAspect, LONG lindex,? void * pvAspect, DVTARGETDEVICE * ptd, HDC hicTargetDev, HDC hdcDraw,? const LPRECTL lprcBounds,
const LPRECTL lprcWBounds, BOOL (*) (DWORD) pfnContinue, DWORD dwContinue )

MSDN参考:http://msdn.microsoft.com/en-us/library/ms688655(VS.85).aspx

?

简单代码示例:

?

[c-sharp]?view plaincopy
  1. IHTMLDocument2*?pDoc?=?...;??//?得到IHTMLDocument2指针??
  2. IViewObject*?pViewObject?=?NULL;??
  3. pDoc->QueryInterface(IID_IViewObject,?(void**)pViewObject);??
  4. pViewObject->(DVASPECT_CONTENT,?1,?NULL,?NULL,?hScreenDC,?hImageDC,?rcSource,?NULL,?NULL,?0);??

?

?

优点:?可以缩放,IE会根据传入的lprcBounds自行缩放图片。

缺点:

因为要计算缩放,速度会较慢;

截取整个文档的可见区域,没法截取特定的元素

有些第三方的ActiveX没有实现IViewObject接口,导致那些ActiveX没有出现在截图里面。

?

3) BOOL?PrintWindow( hwnd,? HDC hdcBlt,? nFlags)

?

MSDN参考:http://msdn.microsoft.com/en-us/library/dd162869(VS.85).aspx

?

简单代码示例:

?

[cpp]?view plaincopy
  1. IWebBrowser2*?pIWebBrowser2?=?...;?//?得到IWebBrowser2指针??
  2. HWND?hTridentWnd=?NULL;????
  3. IOleWindow*?pOleWin?=?NULL;??
  4. pIWebBrowser2->QueryInterface(IID_PPV_ARGS(&pOleWin));??
  5. pOleWin->GetWindow(&hTridentWnd);?//?得到Trident窗口handle?(类名"Internet?Explorer_Server")??
  6. ::PrintWindow(hTridentWnd,?hImageDC,?PW_CLIENTONLY);??

?

?

优点:?内容完整,就算ActiveX没有实现IViewObject接口,也会被截图。

缺点:

只能按目前屏幕显示大小截取,不支持缩放;

速度不如IHTMLElementRender::DrawToDC ?

?

?

注:以上代码示例都是简化版,实际使用请检查函数返回值以及指针有效性。

?

总结

?

综合考虑, PrintWindow 是首选, 简单而且内容完整。 如果你希望得到缩放的结果,那选择IViewObject::Draw。 如果你想要对特定某个元素截图, 那选择IHTMLElementRender::DrawToDC。

?

发表评论
用户名: 匿名