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
簡單代碼示例:
- 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元素
缺點:
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
簡單代碼示例:
- 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自行縮放圖片。
缺點:
3) BOOL PrintWindow( hwnd, HDC hdcBlt, nFlags)
MSDN參考:http://msdn.microsoft.com/en-us/library/dd162869(VS.85).aspx
簡單代碼示例:
- 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接口,也會被截圖。
缺點:
注:以上代碼示例都是簡化版,實際使用請檢查函數返回值以及指針有效性。
總結
綜合考慮, PrintWindow 是首選, 簡單而且內容完整。 如果你希望得到縮放的結果,那選擇IViewObject::Draw。 如果你想要對特定某個元素截圖, 那選擇IHTMLElementRender::DrawToDC。
本文出自 “IE浏覽器研發” 博客,請務必保留此出處http://wingeek.blog.51cto.com/1226974/450216