主要有以下3個接口可以實作IE網頁截圖。
1) HRESULT IHTMLElementRender::DrawToDC(HDC hDC)
簡單代碼示例:
IHTMLDocument3 *pDoc = ...; //得到IHTMLDocument3指針
IHTMLElement *pDocElement = NULL;
pDoc->get_documentElement(&pDocElement );
IHTMLElementRender *pRender = NULL;
pDocElement ->QueryInterface(IID_IHTMLElementRender, (void **) &pRender);
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 )
IHTMLDocument2* pDoc = ...; // 得到IHTMLDocument2指針
IViewObject* pViewObject = NULL;
pDoc->QueryInterface(IID_IViewObject, (void**)pViewObject);
pViewObject->(DVASPECT_CONTENT, 1, NULL, NULL, hScreenDC, hImageDC, rcSource, NULL, NULL, 0);
優點: 可以縮放,IE會根據傳入的lprcBounds自行縮放圖檔。
因為要計算縮放,速度會較慢;
截取整個文檔的可見區域,沒法截取特定的元素
有些第三方的ActiveX沒有實作IViewObject接口,導緻那些ActiveX沒有出現在截圖裡面。
3) BOOL PrintWindow( hwnd, HDC hdcBlt, nFlags)
IWebBrowser2* pIWebBrowser2 = ...; // 得到IWebBrowser2指針
HWND hTridentWnd= NULL;
IOleWindow* pOleWin = NULL;
pIWebBrowser2->QueryInterface(IID_PPV_ARGS(&pOleWin));
pOleWin->GetWindow(&hTridentWnd); // 得到Trident視窗handle (類名"Internet Explorer_Server")
::PrintWindow(hTridentWnd, hImageDC, PW_CLIENTONLY);
優點: 内容完整,就算ActiveX沒有實作IViewObject接口,也會被截圖。
速度不如IHTMLElementRender::DrawToDC
注:以上代碼示例都是簡化版,實際使用請檢查函數傳回值以及指針有效性。
總結
綜合考慮, PrintWindow 是首選, 簡單而且内容完整。 如果你希望得到縮放的結果,那選擇IViewObject::Draw。 如果你想要對特定某個元素截圖, 那選擇IHTMLElementRender::DrawToDC。
本文轉自 陳本峰 51CTO部落格,原文連結:http://blog.51cto.com/wingeek/450216,如需轉載請自行聯系原作者